在java中执行后,如何为下一个任务保存线程(线程池的实现)

时间:2012-10-06 12:22:32

标签: java threadpool

我需要询问有关如何在每次发生任务提交时执行常量线程执行线程池的情况。 (在Executor中避免每次线程创建和删除开销)

executor.submit(Runnable)

让我们说我们在开始时创建一些线程,当任务到来时,我们使用任何Queue impl为它们(Thread)分配任务。但是在完成它的任务之后,如果线程的生命周期中的某个线程如何再次返回其池中

“执行其run方法后,它进入TERMINATED状态,不能再次使用”

我不明白线程池是如何工作的,因为它有一定数量的线程来执行任何任务到它的队列。

如果有人能在完成任务后为我提供线程重用的示例,那将是很棒的。

!!提前谢谢。!!

5 个答案:

答案 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 executionSwing时,Java中的线程变得必不可少。 主要是GUI组件

答案 4 :(得分:0)

我完全同意Peter,但希望添加与ExecutorService执行流程相关的步骤,以便清楚地理解。

  • 如果您创建线程池(固定大小池),则不表示已创建线程。
  • 如果您提交和/或执行新任务(RunnubleCallable),如果创建的线程<池大小计数
  • ,将创建​​新线程JUTS
  • 创建的线程没有返回池,线程可以在阻塞队列中等待新值,这一点我们可以调用RETURNING TO POOL
  • 上面描述的像Peter这样的游泳池高手的所有线程。