2011-07-11 47 views
0

我正在尝试编写多线程程序的一部分,其中来自固定线程池的每个线程都尝试从队列中获取对象,并且如果队列为空,线程将等待。为什么ExecutorService在线程被阻塞时保持执行状态?

我遇到的问题是程序使用的内存不断增加。

public class Ex3 { 

public static LinkedBlockingQueue<Integer> myLBQ = new LinkedBlockingQueue<Integer>(10); 

public static void main(String argc[]) throws Exception { 
    ExecutorService executor = Executors.newFixedThreadPool(3); 
    myLBQ.add(new Integer(1)); 
    for (;;) { 
     executor.execute(new MyHandler(myLBQ)); 
    } 
} 
} 

class MyHandler implements Runnable { 

LinkedBlockingQueue<Integer> myLBQ; 

MyHandler(LinkedBlockingQueue<Integer> myLBQ) { 
    this.myLBQ = myLBQ; 
} 

public void run() { 
    try { 
     myLBQ.take(); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 
} 
} 

我不明白为什么当线程应该等待一个项目添加到队列时,executor.execute会持续触发。如何修改我的代码以反映这一点?

回答

1

这可以尽快向执行者添加任务。

for (;;) { 
    executor.execute(new MyHandler(myLBQ)); 
} 

这将消耗约200 MB每秒。它与任务是否有任何关系没有关系。

如果你不想这样做,我建议你将循环移到runnable并只添加一个。这将导致它永远等待任务。


一个更好的办法是使用的ExecutorService的内置队列中排队的任务。

ExecutorService executor = Executors.newFixedThreadPool(3); 
final int taskId = 1; 
executor.submit(new Runnable() { 
    @Override 
    public void run() { 
     doSomething(taskId); 
    } 
}); 

executor.shutdown(); 

这是做同样的事情,但更简单恕我直言。

+0

谢谢,我没有意识到,无论线程是否可用来执行它们,项目都会被添加到队列中。 – Mat

+0

您可以更改它以拒绝任务,并且没有等待线程,但这通常会导致“RejectedExecutionException”,这不是您想要的。 –

0

这是因为您正在创建一个gazillion MyHandler实例并将它们插入到执行程序的内部队列中。

无限循环是相当的意思。

相关问题