Wystąpiła sytuacja, gdy ThreadPoolExecutor
jest zaparkowany w funkcji execute(Runnable)
, podczas gdy wszystkie wątki czekają w getTask
func, workQueue jest pusta.Zakleszczenie w ThreadPoolExecutor
Czy ktoś ma jakieś pomysły?
ThreadPoolExecutor
jest tworzony ArrayBlockingQueue
i corePoolSize == maximumPoolSize = 4
[Edycja] Bardziej szczegółowo, gwint jest zablokowany w ThreadPoolExecutor.exec(Runnable command)
func. Ma zadanie wykonać, ale tego nie robi.
[Edytuj2] Executor jest zablokowany gdzieś w kolejce roboczej (ArrayBlockingQueue
).
[Edit3] callstack:
thread = front_end(224)
at sun.misc.Unsafe.park(Native methord)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:158)
at
java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:747)
at
java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:778)
at
java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1114)
at
java.util.concurrent.locks.ReentrantLock$NonfairSync.lock(ReentrantLock.java:186)
at java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:262)
at java.util.concurrent.ArrayBlockingQueue.offer(ArrayBlockingQueue.java:224)
at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:653)
at net.listenThread.WorkersPool.execute(WorkersPool.java:45)
w tym samym czasie workQueue pustego (sprawdzone za pomocą pilota zdalnego debugowania)
[Edit4] Kod pracy z ThreadPoolExecutor
:
public WorkersPool(int size) {
pool = new ThreadPoolExecutor(size, size, IDLE_WORKER_THREAD_TIMEOUT, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(WORK_QUEUE_CAPACITY),
new ThreadFactory() {
@NotNull
private final AtomicInteger threadsCount = new AtomicInteger(0);
@NotNull
public Thread newThread(@NotNull Runnable r) {
final Thread thread = new Thread(r);
thread.setName("net_worker_" + threadsCount.incrementAndGet());
return thread;
}
},
new RejectedExecutionHandler() {
public void rejectedExecution(@Nullable Runnable r, @Nullable ThreadPoolExecutor executor) {
Verify.warning("new task " + r + " is discarded");
}
});
}
public void execute(@NotNull Runnable task) {
pool.execute(task);
}
public void stopWorkers() throws WorkersTerminationFailedException {
pool.shutdownNow();
try {
pool.awaitTermination(THREAD_TERMINATION_WAIT_TIME, TimeUnit.SECONDS);
} catch (InterruptedException e) {
throw new WorkersTerminationFailedException("Workers-pool termination failed", e);
}
}
}
Jaki jest charakter zadania przekazywanego do TPE.execute() func.? Jeśli zadanie ma dostęp do TPE, może to być twój problem. – artemv
Myślę, że mam porównywalny problem w wersji 1.7.0_13.Proces rozpoczyna się i działa bez problemu ... a następnie w pewnym momencie mam ~~ 200 zadań, ale moja kolejka blokująca jest pusta. Rozmiar puli rdzeniowej to 3 ... Używam ArrayBlockingQueue też .... – cljk