主线程等待线程池结束

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 workQueue,
      RejectedExecutionHandler handler)
     */

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

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

    ThreadPoolExecutor threadPool2 =  new ThreadPoolExecutor(5, 8, 1,
        TimeUnit.SECONDS,  new LinkedBlockingQueue());
使用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 workQueue)*/

    ThreadPoolExecutor threadPool2 =  new ThreadPoolExecutor(5, 8, 1,
        TimeUnit.SECONDS,  new LinkedBlockingQueue());
     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。

你可能感兴趣的:(java多线程)