我需要询问有关如何在每次发生任务提交时执行常量线程执行线程池的情况。 (在Executor中避免每次线程创建和删除开销)
executor.submit(Runnable)
让我们说我们在开始时创建一些线程,当任务到来时,我们使用任何Queue impl为它们(Thread)分配任务。但是在完成它的任务之后,如果线程的生命周期中的某个线程如何再次返回其池中
“执行其run方法后,它进入TERMINATED状态,不能再次使用”
我不明白线程池是如何工作的,因为它有一定数量的线程来执行任何任务到它的队列。
如果有人能在完成任务后为我提供线程重用的示例,那将是很棒的。
!!提前谢谢。!!
答案 0 :(得分:3)
“执行其run方法后,它进入TERMINATED状态,不能再次使用”
它没有完成它的run()
而是它有一个循环来运行你提供它的任务的run()。
显着简化线程池模式,你有代码看起来像这样。
final BlockingQueue<Runnable> tasks = new LinkedBlockingQueue<Runnable>();
public void submit(Runnable runs) {
tasks.add(runs);
}
volatile boolean running = true;
// running in each thread in the pool
class RunsRunnable implement Runnable {
public void run() {
while(running) {
Runnable runs = tasks.take();
try {
runs.run();
} catch(Throwable t) {
// handles t
}
}
}
}
在这个例子中,您可以看到,当每个任务的run()完成时,线程本身的run()直到池关闭为止。
答案 1 :(得分:1)
通常当我们使用线程池时会发生什么,它的内部Run方法被强制迭代运行。直到队列中有任务可用。
在下面的示例中,pool.removeFromQueue()将以迭代方式运行。
public class MyThread<V> extends Thread {
private MyThreadPool<V> pool;
private boolean active = true;
public boolean isActive() {
return active;
}
public void setPool(MyThreadPool<V> p) {
pool = p;
}
/**
* Checks if there are any unfinished tasks left. if there are , then runs
* the task and call back with output on resultListner Waits if there are no
* tasks available to run If shutDown is called on MyThreadPool, all waiting
* threads will exit and all running threads will exit after finishing the
* task
*/
@Override
public void run() {
ResultListener<V> result = pool.getResultListener();
Callable<V> task;
while (true) {
task = pool.removeFromQueue();
if (task != null) {
try {
V output = task.call();
result.finish(output);
} catch (Exception e) {
result.error(e);
}
} else {
if (!isActive())
break;
else {
synchronized (pool.getWaitLock()) {
try {
pool.getWaitLock().wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
}
void shutdown() {
active = false;
}
需要设计线程池
public MyThreadPool(int size, ResultListener<V> myResultListener) {
tasks = new LinkedList<Callable<V>>();
threads = new LinkedList<MyThread<V>>();
shutDown = false;
resultListener = myResultListener;
for (int i = 0; i < size; i++) {
MyThread<V> myThread = new MyThread<V>();
myThread.setPool(this);
threads.add(myThread);
myThread.start();
}
}
答案 2 :(得分:0)
您可以在此处查看:http://www.ibm.com/developerworks/library/j-jtp0730/index.html了解更多详情和实施示例。如果队列为空,则池中的线程将等待,并且一旦通知队列具有某些元素,则每个线程都会启动consome消息。
答案 3 :(得分:0)
ExecutorService executor = Executors.newFixedThreadPool(2);
- 上述语句创建了一个固定大小为2的ThreadPool。
executor.execute(new Worker());
- 以上语句采用已实现Runnable
接口的类Worker的实例。
- 现在Executors
是一个中间对象,执行任务。它管理线程对象。
- 通过执行上述语句,将执行run()
方法,一旦run()方法完成,线程不会进入死态但是回到池中,等待分配给它的另一个工作,所以它可以再次进入Runnable状态然后再运行,所有这些都由Executors处理。
executor.shutdown();
- 上面的语句将关闭Executors本身,优雅地处理由它管理的所有线程的关闭.. shutdown()
在该中心对象上,而后者又可以终止每个注册执行人。
////////// Edited Part//////////////////////
- 首先,Runnable有一个run()方法,它不能返回任何东西,而run()方法不能抛出一个已检查的异常,因此在Java 5中引入了Callable,它是参数类型的,并且有一个名为call()的方法,它能够返回并抛出Checked异常。
现在看一下这个例子:
Thread t = new Thread(new Worker());
t.run();
t.start();
- t.run()
只是对run()
方法的简单调用,这不会跨越 thread of execution
。
- t.start()
然后为initialization
的{{1}}准备重要内容,然后调用 thread of execution
1}} run()
的方法,然后将Runnable
分配给 新形成的 Task
,然后返回迅速.... 强>
使用thread of execution
和Swing
时,Java中的线程变得必不可少。 主要是GUI组件。
答案 4 :(得分:0)
我完全同意Peter,但希望添加与ExecutorService执行流程相关的步骤,以便清楚地理解。
Runnuble
或Callable
),如果创建的线程<
池大小计数