GAE just blocks forever when I try to complete ExecutorService. Small sample below:
ThreadFactory threadFactory = ThreadManager.currentRequestThreadFactory();
ExecutorService pool = Executors.newSingleThreadExecutor(threadFactory);
Future<String> future = pool.submit(new Callable<String>() {
public String call() throws Exception {
return "Hello from Thread";
}
});
LOG.info("Result is: [" + future.get() + "]. Pool expected to be idle now");
pool.shutdown();
if (!pool.awaitTermination(1, TimeUnit.SECONDS)) {
LOG.info("Pool does not like shutdown()");
pool.shutdownNow();
if (!pool.awaitTermination(1, TimeUnit.SECONDS)) {
LOG.info("Pool does not even like shutdownNow()");
}
}
The same code works without blocking at startup locally, it just blocks without completion at startup, deployed to AppEngine. The timeout can be increased until the 60 second request limit leads to code interruption.
This seems to be a subtle but dangerous difference from the standard JVM. Regularly typed code for cleaning can significantly kill your service. ThreadManagerThe documentation mentions that streams are a little special, but they are - as I understand it - interrupted and designed to be terminated.
- Is this just me (some library using streams)?
- //- ?
, pool.shutdown(), , ? - .
# 1
. Thread. :
final CountDownLatch threadEnter = new CountDownLatch(1);
final Object wait4Interrupt = new Object();
Runnable task = new Runnable() {
public void run() {
synchronized (wait4Interrupt) {
threadEnter.countDown();
try {
wait4Interrupt.wait();
} catch (InterruptedException e) {
LOG.info("Thread got interrupted.");
Thread.currentThread().interrupt();
}
}
}
};
Thread thread = ThreadManager.createThreadForCurrentRequest(task);
LOG.info("Thread log #1: " + thread + " " + thread.getState());
thread.start();
threadEnter.await();
synchronized (wait4Interrupt) {
LOG.info("Thread log #2: " + thread + " " + thread.getState());
thread.interrupt();
}
thread.join(1000);
LOG.info("Thread log #3: " + thread + " " + thread.getState());
:
I 16:08:37.213 Thread log #1: Thread[Thread-7,5,Request #0] NEW
I 16:08:37.216 Thread log #2: Thread[Thread-7,5,Request #0] WAITING
I 16:08:37.216 Thread got interrupted.
I 16:08:37.217 Thread log #3: Thread[Thread-7,5,] TERMINATED
, factory, , , join() 'd . ExecutorService?
# 2
pool.toString() № 1 shutdown()
java.util.concurrent.ThreadPoolExecutor@175434a
[Shutting down, pool size = 1, active threads = 0, queued tasks = 0, completed tasks = 1]
, , , active threads = 0.
# 3
, , . 500 . future.get() .
Future<String> future = pool.submit(new Callable<String>() {
public String call() throws Exception {
Thread.sleep(500);
return "Hello from Thread";
}
});
pool.shutdown();
pool.awaitTermination(2, TimeUnit.SECONDS);
= > . .