ThreadPoolExecutor不将任务分配给工作线程

时间:2017-03-13 13:38:39

标签: 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().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());

提交任务:

Future<?> futureTask = executor.submit(opmTask); 

任务:

 class OpmTask implements Runnable { 
@Override public void run() {
 .... }
 } 

线程管理杀死阻塞线程

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

1 个答案:

答案 0 :(得分:1)

从你的例子来看,这有点难以理解。我建议首先制作你的线程守护进程,这样它们就不会阻止你的应用程序关闭。至于你的例子,我看不出任何不当行为。试试这个例子:

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)

请注意,这将永远运行并在一行一行后打印下一行。也不是说我传递的ThreadFactory将执行程序的线程配置为守护进程。

至于你的stacktrace:

ArrayBlockingQueue#take

这并不意味着你的线程被卡住了。 (从技术上讲,它确实如此,但实际上并非如此)。他们正在等待新任务的开展。如果您查看队列实施: public E take() throws InterruptedException { final ReentrantLock lock = this.lock; lock.lockInterruptibly(); try { while (count == 0) notEmpty.await(); return dequeue(); } finally { lock.unlock(); } }

{{1}}

这是他们等待新任务的地方。他们检查队列是否还有其他事情要做,然后等到队列。这自然会发生在你的所有线程上。

我也发现配置有点奇怪。您可以使用最大大小为1的队列配置100个工作程序。这似乎是删除任务的方法。

此外,您没有显示您的任务实现,这意味着我只是猜测您的线程池在异常上的行为。

您的设置似乎正常,但问题在于任务或提交本身。