在java(线程池的实现)中执行下一个任务后,我们如何保存线程以供下一个任务使用
我需要询问如何实现线程池,以便在每次任务提交时都有固定数量的线程执行。(在Executor中,以避免每次线程创建和删除的开销) 假设我们在开始时创建一些线程,当任务到来时,我们使用任何队列impl将任务分配给它们(线程)。但是,在完成任务后,线程如何能够再次返回其池,而按照线程的生命周期来说 “执行其运行方法后,它将进入终止状态,无法再次使用” 我不明白线程池是如何工作的,因为它有固定数量的线程来执行队列中的任何任务 如果有人能给我提供一个线程在完成任务后重用的例子,那就太好了 !!提前感谢 “执行其运行方法后,它将进入终止状态,无法再次使用” 它没有完成它的在java(线程池的实现)中执行下一个任务后,我们如何保存线程以供下一个任务使用,java,threadpool,Java,Threadpool,我需要询问如何实现线程池,以便在每次任务提交时都有固定数量的线程执行。(在Executor中,以避免每次线程创建和删除的开销) 假设我们在开始时创建一些线程,当任务到来时,我们使用任何队列impl将任务分配给它们(线程)。但是,在完成任务后,线程如何能够再次返回其池,而按照线程的生命周期来说 “执行其运行方法后,它将进入终止状态,无法再次使用” 我不明白线程池是如何工作的,因为它有固定数量的线程来执行队列中的任何任务 如果有人能给我提供一个线程在完成任务后重用的例子,那就太好了 !!提前感谢 “
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
}
}
}
}
final BlockingQueue tasks=new LinkedBlockingQueue();
公共作废提交(可运行运行){
任务。添加(运行);
}
volatile boolean running=true;
//在池中的每个线程中运行
类RunsRunnable实现Runnable{
公开募捐{
(跑步时){
Runnable runs=tasks.take();
试一试{
runs.run();
}捕获(可丢弃的t){
//处理
}
}
}
}
在本例中,您可以看到,当每个任务的run()完成时,线程本身的run()直到池关闭后才会运行。您可以在此处查看:有关更多详细信息和实现示例。如果队列为空,池中的线程将等待,并且在通知每个线程队列有一些元素后,它们都将启动consome消息 ExecutorService executor=Executors.newFixedThreadPool(2)代码> -上述语句创建了一个固定大小为2的线程池
executor.execute(新工作者())代码>
-上面的语句以实现了Runnable
接口的类工作者的实例为例
-现在这里的执行者是执行任务的中间对象。它管理线程对象
-通过执行上述语句,将执行run()
方法,并且一旦run()方法完成,线程就不会进入死状态,而是回到池中,等待为其分配另一个工作,这样它就可以再次进入可运行状态,然后再运行,所有这些都由遗嘱执行人处理
executor.shutdown()代码>
-上述语句将关闭执行器本身,优雅地处理该中心对象上由其管理的所有线程的关闭。shutdown()
,这反过来可能会终止每个已注册的执行器
////////// Edited Part//////////////////////
-首先,Runnable有一个run()方法,它不能返回任何东西,run()方法不能抛出检查过的异常,因此在Java 5中引入了Callable,它是参数化类型,有一个名为call()的方法,它能够返回和抛出检查过的异常
现在看这个例子:
Thread t = new Thread(new Worker());
t.run();
t.start();
-t.run()
只是对run()
方法的简单调用,这不会跨越执行线程
-t.start()
而则为执行线程的初始化
做重要准备,然后调用可运行
的run()
方法,然后将任务分配给新形成的执行线程,然后快速返回..
当使用Swing
和AWT
时,Java中的线程成为一种必需品主要是GUI组件我完全同意Peter的观点,但我希望添加与ExecutorService执行流程相关的步骤,以便清楚地理解
- 如果创建线程池(固定大小的池),并不意味着创建了线程
- 如果您提交和/或执行新任务(
Runnuble
或Callable
),如果创建的线程数增加,将创建新线程通常情况下,当我们使用线程池时,其内部运行方法将强制迭代运行。直到队列中有可用的任务
在下面的示例中,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;
}
公共类MyThread扩展线程{
私人游泳池;
private boolean active=true;
公共布尔isActive(){
主动返回;
}
公共无效设置池(MyThreadPool p){
pool=p;
}
/**
*检查是否还有未完成的任务。如果有,则运行
*如果没有响应,则resultListner上的任务和带输出的回调将等待
*在MyThreadPool上调用shutDown时可运行的任务,所有任务都在等待
*线程将退出,所有正在运行的线程将在完成任务后退出
*任务
*/
@凌驾
公开募捐{
ResultListener result=pool.getResultListener();
可调用任务;
while(true){
task=pool.removeFromQueue();
如果(任务!=null){
试一试{
V output=task.call();
结果。完成(输出);
}捕获(例外e){
结果:误差(e);
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();
}
}