Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java ThreadPoolExecutor未将任务分配给工作线程_Java_Multithreading_Java.util.concurrent_Threadpoolexecutor - Fatal编程技术网

Java 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

我的ThreadPoolExecutor没有将任务分配给工作线程。由于我不知道这个问题是如何产生的,所以我将解释目前的情况

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();
        }
    }