Java 正在中断线程池中的BlockingQueue take()
我有一个线程池,它创建工人,工人从Java 正在中断线程池中的BlockingQueue take(),java,multithreading,threadpool,blockingqueue,Java,Multithreading,Threadpool,Blockingqueue,我有一个线程池,它创建工人,工人从阻塞队列获取作业。 线程等待队列中的take()。 即使显式调用运行线程的线程中断方法,它们仍然在等待take()。处理阻塞队列的正确方法是什么 public class ThreadPoolGen { static final Logger LOG = Logger.getLogger(ThreadPoolGen.class); private LinkedBlockingQueue<Runnable> queue; pr
阻塞队列
获取作业。
线程等待队列中的take()
。
即使显式调用运行线程的线程中断方法,它们仍然在等待take()
。处理阻塞队列的正确方法是什么
public class ThreadPoolGen {
static final Logger LOG = Logger.getLogger(ThreadPoolGen.class);
private LinkedBlockingQueue<Runnable> queue;
private int threadCount;
private Worker[] workers;
private Thread[] workerThreads;
public ThreadPoolGen(int count) throws CountException{
if(isValidCount(count))
this.threadCount = count;
else
throw new CountException("Invalid Thread Count");
workers = new Worker[count];
workerThreads = new Thread[count];
queue = new LinkedBlockingQueue<Runnable>();
startThreads();
}
public boolean execute(Runnable task){
return queue.offer(task);
}
private void startThreads(){
synchronized (this) {
for(int i=0;i<threadCount;i++){
workers[i] = new Worker();
workerThreads[i] = new Thread(workers[i]);
workerThreads[i].start();
}
}
}
public boolean shutDown(){
try{
for(Worker w: workers){
w.thread.interrupt();
}
queue.clear();
for(Thread workerThread : workerThreads){
workerThread.interrupt();
}
return true;
}catch(Exception e){
LOG.debug(Thread.currentThread()+": Worker Thread Shutdown Failed");
return false;
}
}
private boolean isValidCount(int count){
if(count<Integer.MAX_VALUE && count>0)
return true;
else
return false;
}
private class Worker implements Runnable{
final Thread thread;
private Worker(){
this.thread = Thread.currentThread();
}
@Override
public void run() {
try{
while(true){
try{
Runnable r = queue.take();
r.run();
}catch(InterruptedException interrupt){
LOG.debug("Interrupted exception in: "+thread.getName());
}
}
}catch(Exception intr){
this.thread.interrupt();
}finally{
this.thread.interrupt();
}
}
}
}
您正在
while
循环中捕获异常
while (true) {
try {
Runnable r = queue.take();
r.run();
} catch (InterruptedException interrupt) {
LOG.debug("Interrupted exception in: " + thread.getName());
}
}
任何时候你中断这个线程,它都会再次循环。摆脱这个试试catch
。让外部的一个(在之外,而
)处理中断异常
请注意,当线程执行run()
时,您可能会得到中断
,在这种情况下,中断异常
可能不会达到预期效果。您可能应该设置一个标志,以便在Runnable#run()
完成后,同一线程不会再次循环
我有一个线程池,它创建工人,工人从阻塞队列中获取作业。线程等待队列中的take()。即使显式调用运行线程的线程中断方法,它们仍然在等待take()。处理阻塞队列的正确方法是什么
在我看来,您正在复制ExecutorService
的行为。这有什么原因吗?以下是:
有时,运行的线程需要保存上下文,但您的类似乎过于复杂。您仍然可以使用生产者线程和消费者线程之间共享阻塞队列的ExecutorService
。您可以在完成时中断线程,但也可以将count
数量的null
对象推入队列,并在工作线程看到null
时退出
public class Worker implements Runnable {
// some sort of context needed to be held by each runner
public void run() {
while (true) {
Work work = sharedQueue.take();
if (work == null) {
return;
}
// do the work ...
}
}
}
如何知道线程正在等待take()?在用remove()替换take时,线程按预期退出添加volatile标志有效,但这是处理线程关闭的正确方法吗?@arpitpanwar关闭线程池是一项非常重要的任务。查看ThreadPoolExecutor
的源代码,了解一个复杂的示例。ExecutorService没有被使用,我想实现我自己的线程池。我纠正了这个问题,在队列中放入了一个对象,表示线程必须退出,并设置了一个标志,使线程中断while循环
ExecutorService threadPool = Executors.newFixedThreadPool(count);
...
threadPool.submit(new Runnable() ...);
public class Worker implements Runnable {
// some sort of context needed to be held by each runner
public void run() {
while (true) {
Work work = sharedQueue.take();
if (work == null) {
return;
}
// do the work ...
}
}
}