2012-10-06 31 views
5

我需要问一下如何在发生任务提交时每次执行线程数量不变时执行线程池。使用任何队列IMPL(在执行人避免每次线程的创建和删除的开销)我们如何在Java中执行下一个任务后保存下一个任务(线程池实现)

executor.submit(Runnable) 

假设我们在开始创建一些线程和任务时,我们来分配任务给他们(线程)。但在完成后的任务怎么可能一个线程返回到其池时再为每个线程的生命周期中说,

“它的run方法执行后它进入终止状态,不能再使用”

我不明白线程池是如何工作的,以便有恒定数量的线程执行任何任务到其队列。

如果有人能够在任务完成后为我提供一个线程重用的例子,那将会很棒。

!!在此先感谢。

+0

概念上它很容易。您启动一个固定数量的运行方法在队列中等待的队列。您将工作请求发送到队列,运行方法将请求解除队列并执行工作请求。然后他们又回到队列中等待。诀窍是找到正确类型的队列--JDK中有六个,但只有一个特殊的(最后我看了)适合这个,它隐藏在一个角落里。 –

回答

2

“它的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()的线程中的每个任务完成后,运行()本身并不直到池是关机。

+0

但是如果我们直接执行run方法,那么没有线程会产生,它只会执行这个方法。那么它是否意味着执行(在自定义impl中)可以接受任何具有相同合约的任务(如Runnable已经运行()),我们必须在池线程中调用该合约方法。没有使用Runnable或Callable作为任务? – Virendra

+0

我已经添加了一个例子。我认为你假设当Runtime.run()返回时,当它只是一个方法调用时会发生一些特殊情况。当没有其他任何事情时,线程停止。 BTW UncaughtExceptionHandler可以在run()退出后调用,以便线程不会立即终止。 –

0

你可以看看这里:http://www.ibm.com/developerworks/library/j-jtp0730/index.html了解更多细节和实施例。如果队列为空,则池中的线程将等待,并且一旦收到队列中有某些元素的通知,它们将分别启动合适的消息。

+0

同样的问题在这里。为什么当他们只用于调用他们的合同方法时,有必要将任务设置为Runnable或Callable。 r =(Runnable)queue.removeFirst(); r.run(); 是否有必要只有Runnable。我们可以对任何其他运行方法的对象进行分析。因为它的最终目标是使用不超过该线程的线程来调用? – Virendra

0

ExecutorService executor = Executors.newFixedThreadPool(2);

-上述语句创建的线程池具有2

executor.execute(new Worker());

固定大小 -上述语句采用类工人已实现Runnable的一个实例接口。

-现在这里Executors是一个中间对象,执行任务。它管理线程对象。

-通过执行上面的语句run()方法将被执行,而一旦run()方法完成后,线程亘古进入死亡状态,但移动放回池中,等待有另一个工作分配所以它可以再次进入Runnable状态,然后运行,所有这些都由Executors处理。

executor.shutdown();

-上面的语句将关闭执行人本身,适当地处理其管理的所有线程的关机.. shutdown()该中心对象,这反过来又可以终止每个注册执行人对。

////////// Edited Part////////////////////// 

- 所有可运行的首先有一个run()方法,该方法不能返回任何东西,和run()方法不能抛出checked异常,因此可赎回在Java 5中,这是参数化类型的介绍,并有一个名为call()的方法,它能够返回并抛出Checked异常。

现在看到这个例子:

Thread t = new Thread(new Worker()); 

t.run(); 

t.start(); 

-t.run()仅仅是run()方法的简单的通话,这不会跨越一个thread of execution

-t.start()而准备的东西为thread of executioninitialization重要,然后电话run()方法Runnable,然后分配Task新成立的thread of execution快速返回....

使用Swing和时,Java中的线程成为必需。 主要是GUI组件

+0

@Vivek可以请你回答我在下面的问题中提出的问题。为什么任务为Runnable或Callable。我可以给它任何有run()方法的obj。因为pooling线程只调用run()而不是从它创建任何线程。那么实际上不需要Runnable? – Virendra

+0

@Virendra请看我的编辑答案..... –

+0

所以在执行器的情况下,t.run()正在工作,因为我们在执行任务时不会创建任何t.start()调用。因此,这与提供任何可能不是Ru​​nnable实现的任务相同,但它具有run()方法。作为Executor的PoolWorker只执行run方法(如t.run())在任务中不使用线程质量? – Virendra

0

我完全同意彼得,但想要添加与ExecutorService执行流程相关的步骤,以便清楚理解。

  • 如果你创建的线程池(固定大小的池)并不意味着创建线程。
  • 如果提交和/或执行新的任务(RunnubleCallable)新的线程将被创建伸出如果创建的线程<大小池的
  • 创建的线程不返回到池的数量,线程可以阻塞等待新的价值队列,这一点我们可以调用返回到池
  • 所有线程池执行像像上面描述的彼得。
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(); 
     } 
    } 
相关问题