Java ThreadPoolExecutor未将任务分配给工作线程
我的ThreadPoolExecutor没有将任务分配给工作线程。由于我不知道这个问题是如何产生的,所以我将解释目前的情况Java ThreadPoolExecutor未将任务分配给工作线程,java,multithreading,java.util.concurrent,threadpoolexecutor,Java,Multithreading,Java.util.concurrent,Threadpoolexecutor,我的ThreadPoolExecutor没有将任务分配给工作线程。由于我不知道这个问题是如何产生的,所以我将解释目前的情况 CorePoolSize = 15, Max PoolSize = 100, KeepAliveTime 5 minutes, ArrayBlockingQueue of size 1. 目前 executor.getActiveCount() = 0, executor.getPoolSize() = 100, executor.getQueue().rema
CorePoolSize = 15,
Max PoolSize = 100,
KeepAliveTime 5 minutes,
ArrayBlockingQueue of size 1.
目前
executor.getActiveCount() = 0,
executor.getPoolSize() = 100,
executor.getQueue().remainingCapacity() = 0
我可以看到我提交的任务在ArrayBlockingQueue中,但为什么这100个线程只是坐在线程池中,没有人挑选提交的任务呢
jconsole中具有类似堆栈跟踪的所有线程
Name: pool-15-thread-182
State: WAITING on java.util.concurrent.locks.ReentrantLock$NonfairSync@16926fe3
Total blocked: 396 Total waited: 66
Stack trace:
sun.misc.Unsafe.park(Native Method)
java.util.concurrent.locks.LockSupport.park(LockSupport.java:156)
java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:811)
java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:842)
java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2033)
java.util.concurrent.ArrayBlockingQueue.poll(ArrayBlockingQueue.java:347)
java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:955)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:917)
java.lang.Thread.run(Thread.java:682)
代码
初始化:
executor = new ThreadPoolExecutor(CORE_THREADPOOL_SIZE, (int)MAX_THREADPOOL_SIZE, KEEP_ALIVE_TIME, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(1), new ThreadPoolExecutor.AbortPolicy());
终止阻塞线程的线程管理
if(future != null && !future.isDone()){
future.cancel(true);
}
// after 30 minutes of above code if still blocking thread running
if(thread.isAlive()){
thread.stop();
}
在内部运行一些内部方法
while (true) {
while (InputStream.available() > 0) {
int i = in.read(tmp, 0, 1024);
if (i < 0)
break;
outputStr += new String(tmp, 0, i);
}
if(Thread.interrupted()){
logger.log(Level.SEVERE,"Thread interrupted");
throw new BlockedThreadException("Thread interrupted");
}
}
从你的例子来看,这有点难以理解。首先,我建议您将线程设置为守护进程,这样它们就不会阻止您的应用程序关闭。至于你的例子,我看不出有任何不当行为。试试这个例子:
public class ExecutorTest {
public static void main(String[] args) throws InterruptedException, ExecutionException {
ThreadPoolExecutor executor = new ThreadPoolExecutor(10, (int)10, 5 * 60 , TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(1), new ThreadFactoryBuilder().setDaemon(true).build());
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());
while(true) {
executor.submit(() -> {
System.out.println("Executing " + UUID.randomUUID().toString());
});
Thread.sleep(1000);
}
}
}
这并不意味着线程被卡住。嗯,从技术上讲是这样,但不是在实际意义上。他们正在等待一项新任务。如果您查看队列实现:ArrayBlockingQueuetake
这是他们等待新任务的地方。他们检查队列是否有其他事情要做,然后等待它做。这将自然地发生在所有线程中
我还发现配置有点奇怪。您可以为100个工作人员配置最大大小为1的队列。这似乎是一个放弃任务的方法
此外,您没有显示任务实现,这意味着我只是猜测线程池在异常情况下的行为
看起来您的设置工作正常,但问题在于任务或提交本身 你能附上你的密码吗?在没有看到它的情况下调试是很困难的。这样我们就可以阅读了。非常感谢。提取任务需要时间,因此您可能会看到一个N的队列。睡眠线程可能需要10-100微秒才能醒来并抓取任务。能否请您先尝试增加队列的容量?我认为您需要创建一个简短的可重复测试。很有可能你做错了什么,但无法从给出的信息中确定是什么。
while (true) {
while (InputStream.available() > 0) {
int i = in.read(tmp, 0, 1024);
if (i < 0)
break;
outputStr += new String(tmp, 0, i);
}
if(Thread.interrupted()){
logger.log(Level.SEVERE,"Thread interrupted");
throw new BlockedThreadException("Thread interrupted");
}
}
public class ExecutorTest {
public static void main(String[] args) throws InterruptedException, ExecutionException {
ThreadPoolExecutor executor = new ThreadPoolExecutor(10, (int)10, 5 * 60 , TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(1), new ThreadFactoryBuilder().setDaemon(true).build());
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());
while(true) {
executor.submit(() -> {
System.out.println("Executing " + UUID.randomUUID().toString());
});
Thread.sleep(1000);
}
}
}
Stack trace:
sun.misc.Unsafe.park(Native Method)
java.util.concurrent.locks.LockSupport.park(LockSupport.java:156)
java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:1987)
java.util.concurrent.ArrayBlockingQueue.take(ArrayBlockingQueue.java:322)
java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:957)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:917)
java.lang.Thread.run(Thread.java:682)
public E take() throws InterruptedException {
final ReentrantLock lock = this.lock;
lock.lockInterruptibly();
try {
while (count == 0)
notEmpty.await();
return dequeue();
} finally {
lock.unlock();
}
}