主线程等待线程池结束

来源:互联网 发布:个人名片设计软件 编辑:程序博客网 时间:2024/05/22 16:32

http://dongdong1314.blog.51cto.com/389953/224932/


所有 SynchronousQueue,它将任务直接提交给线程而不保持它们。在此,如果不存在可用于立即运行任务的线程,则试图把任务加入队列将失败,因此会构造一个新的线程。此策略可以避免在处理可能具有内部依赖性的请求集时出现锁。直接提交通常要求无界 maximumPoolSizes 以避免拒绝新提交的任务。当命令以超过队列所能处理的平均数连续到达时,此策略允许无界线程具有增长的可能性。

  • 无界队列。使用无界队列(例如,不具有预定义容量的 ArrayBlockingQueue)有助于防止资源耗尽,但是可能较难调整和控制。队列大小和最大池大小可能需要相互折衷:使用大型队列和小型池可以最大限度地降低 CPU 使用率、操作系统资源和上下文切换开销,但是可能导致人工降低吞吐量。如果任务频繁阻塞(例如,如果它们是 I/O 边界),则系统可能为超过您许可的更多线程安排时间。使用小型队列通常要求较大的池大小,CPU 使用率较高,但是可能遇到不可接受的调度开销,这样也会降低吞吐量.                                           Above from Javadoc1.6

    创建线程池,有多种构造函数。如下两种:
    /*public ThreadPoolExecutor(int corePoolSize,
          int maximumPoolSize,
          long keepAliveTime, TimeUnit unit,
          BlockingQueue<Runnable> workQueue,
          RejectedExecutionHandler handler)
         */

        ThreadPoolExecutor threadPool = new ThreadPoolExecutor(5, 5, 3,
            TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(100),
            new ThreadPoolExecutor.AbortPolicy());

    /*public ThreadPoolExecutor(int corePoolSize,
                                                        int maximumPoolSize,
                                                        long keepAliveTime,
                                                        TimeUnit unit,
                                                        BlockingQueue<Runnable> workQueue)*/

        ThreadPoolExecutor threadPool2 = new ThreadPoolExecutor(5, 8, 1,
            TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());
    使用LinkedBlockingQueue,即不限队列大小,这时maximumPoolSize无效。池中线程数最多为corePoolSize

    下面想要完成这样的功能:
    主线程在线程池中所有线程结束后才继续执行或结束。
    import java.util.concurrent.LinkedBlockingQueue;
    import java.util.concurrent.ThreadPoolExecutor;
    import java.util.concurrent.TimeUnit;


    public class TestThreadPool {
      public static void main(String[] args) {

        System.out.println("main thread started!");    
        /*public ThreadPoolExecutor(int corePoolSize,
                                                        int maximumPoolSize,
                                                        long keepAliveTime,
                                                        TimeUnit unit,
                                                        BlockingQueue<Runnable> workQueue)*/

        ThreadPoolExecutor threadPool2 = new ThreadPoolExecutor(5, 8, 1,
            TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());
        for (int i = 0; i < 10; i++) {   
          threadPool2.execute(new Task(i));
        }
        threadPool2.shutdown(); //关闭后不能加入新线程,队列中的线程则依次执行完
        while(threadPool2.getPoolSize()!=0);
        System.out.println("main thread end!");
      }
    }

    class Task implements Runnable{
      int count;
      Task(int i){
        this.count = i;
      }
      public void run() {
        try {
          System.out.println("in thread "+count);
          Thread.sleep(10000);
        } catch (InterruptedException e) {
          e.printStackTrace();
        }    

        System.out.println("    thread "+count+" end!");
      }  
    }
    /*
     main thread started!
    in thread 1
    in thread 0
    in thread 2
    in thread 3
    in thread 4
      thread 1 end!
    in thread 5
      thread 3 end!
    in thread 6
      thread 2 end!
    in thread 7
      thread 0 end!
    in thread 8
      thread 4 end!
    in thread 9
      thread 5 end!
      thread 8 end!
      thread 7 end!
      thread 6 end!
      thread 9 end!
    main thread end!
     */
    采用的是getPoolSize()返回当前池中的线程数,程序也说明shutdown虽然关闭线程池操作,但只是不加入新线程,而线程池队列中的线程仍将继续执行完成后,才会最后关闭。因此在池中线程未结束时当前线程数不为0.

    原来使用thread.join(),在不用线程池时很容易使用,join()似乎要在thread.start()后才能有效,而线程池则直接用threadPool.execute(runnable or thread),用join()无效。
        for (int i = 0; i < 10; i++) {
          Thread t = new Thread(new Task(i), "thread " + i);      
          threadPool2.execute(new Task(i));
          //t.start();
          try {
            t.join();//never effective
          } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
          }
        }
        threadPool2.shutdown(); //关闭后不能加入新线程,队列中的线程则依次执行完
        //threadPool2.shutdownNow(); //立即中断停止线程执行,返回等待执行的任务列表
        System.out.println("main thread end!");
    /*
    main thread started!
    in thread 0
    in thread 1
    main thread end!
    in thread 2
    in thread 3
    in thread 4
      thread 1 end!
    in thread 5
      thread 0 end!
    in thread 6
      thread 4 end!
    in thread 7
      thread 3 end!
    in thread 8
      thread 2 end!
    in thread 9
      thread 5 end!
      thread 6 end!
      thread 9 end!
      thread 8 end!
      thread 7 end!
     */

    今天发现threadPoolExecutor.isTerminated()可以代替比较,该函数表示如果关闭后所有任务都已完成,则返回true。另一函数threadPoolExecutor.isTerminating()则表示如果此执行程序处于在 shutdown 或 shutdownNow 之后正在终止但尚未完全终止的过程中,则返回 true。

  • 0 0
    原创粉丝点击