我有一个创建工人的线程池,工作人员从BlockingQueue
获取工作。
线程在队列中等待take()
。
即使在为正在运行的线程显式调用线程中断方法时,它们仍在等待take()
。什么是处理blockingqueue
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();
}
}
}
}
通话类:
public class Runner {
public static void main(String[] args) {
try {
System.out.println("BeforeLaunch");
ThreadPoolGen gen = new ThreadPoolGen(10);
gen.execute(new Runnable() {
@Override
public void run() {
System.out.println("Inside Runnable");
}
});
gen.shutDown();
} catch (CountException ce) {
} catch (Exception e) {
}
}
}
答案 0 :(得分:1)
您正在while
循环
while (true) {
try {
Runnable r = queue.take();
r.run();
} catch (InterruptedException interrupt) {
LOG.debug("Interrupted exception in: " + thread.getName());
}
}
每次中断此线程时,它都会再次循环。摆脱这个try-catch
。让外部的(while
之外)处理InterruptedException
。
请注意,在线程执行interrupt
时,您可能会获得run()
,在这种情况下,InterruptedException
可能无法达到预期效果。你应该设置一个标志,这样一旦完成Runnable#run()
,同一个线程就不会再循环。
答案 1 :(得分:1)
我有一个创建工作人员的线程池,工作人员从BlockingQueue中获取作业。线程在队列中等待take()。即使在为正在运行的线程显式调用线程中断方法时,它们仍在等待take()。什么是处理
BlockingQueue
的正确方法。
在我看来,您正在复制ExecutorService
的行为。是否有一个原因?这是tutorial for them:
ExecutorService threadPool = Executors.newFixedThreadPool(count);
...
threadPool.submit(new Runnable() ...);
有时需要由正在运行的线程保存上下文,但看起来您的类似乎过于复杂。您仍然可以使用在生产者和使用者线程之间共享ExecutorService
的{{1}}。您可以在完成后中断线程,但也可以将BlockingQueue
个count
个对象放入队列,并在看到null
时让工作线程退出。
null