创建线程 
创建普通对象,只是在JVM的堆里 分配一块内存而已 
创建线程,需要调用操作系统内核的API ,然后操作系统需要为线程分配一系列资源,成本很高
线程是一个重量级对象 ,应该避免频繁创建和销毁,采用线程池 方案 
 
 
 
一般的池化资源 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 class  ThreadPool  {         Thread acquire ()  {     }          void  release (Thread t)  {     } } ThreadPool pool; Thread  T1  =  pool.acquire();T1.execute(() -> {      }); 
生产者-消费者模式 业界线程池的设计,普遍采用生产者-消费者模式 ,线程池的使用方是生产者,线程池本身是消费者
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 public  class  MyThreadPool  {         class  WorkerThread  extends  Thread  {         @Override          public  void  run ()  {                          while  (true ) {                 Runnable  task  =  null ;                 try  {                     task = workQueue.take();                 } catch  (InterruptedException e) {                 }                 task.run();             }         }     }          private  BlockingQueue<Runnable> workQueue;          List<WorkerThread> threads = new  ArrayList <>();     public  MyThreadPool (int  poolSize, BlockingQueue<Runnable> workQueue)  {         this .workQueue = workQueue;         for  (int  i  =  0 ; i < poolSize; i++) {             WorkerThread  work  =  new  WorkerThread ();             work.start();             threads.add(work);         }     }          public  void  execute (Runnable command)  throws  InterruptedException {         workQueue.put(command);     }     public  static  void  main (String[] args)  throws  InterruptedException {                  BlockingQueue<Runnable> workQueue = new  LinkedBlockingQueue <>(2 );                  MyThreadPool  pool  =  new  MyThreadPool (10 , workQueue);                  pool.execute(() -> {             System.out.println("hello" );         });     } } 
Java线程池 ThreadPoolExecutor 1 2 3 4 5 6 7 8 9 10 public  ThreadPoolExecutor (int  corePoolSize,                           int  maximumPoolSize,                           long  keepAliveTime,                           TimeUnit unit,                           BlockingQueue<Runnable> workQueue,                           ThreadFactory threadFactory,                           RejectedExecutionHandler handler) public  void  allowCoreThreadTimeOut (boolean  value) 
corePoolSize:线程池保有的最小 线程数 
maximumPoolSize:线程池创建的最大 线程数 
keepAliveTime & unit
如果一个线程空闲了keepAliveTime & unit,并且线程池的线程数大于corePoolSize,那么这个空闲的线程就要被回收  
 
 
workQueue:工作队列 
threadFactory:自定义如何创建线程 
handler
线程池中的所有线程都很忙碌,并且工作队列也满了(工作队列是有界 队列),此时提交任务,线程池会拒绝接收  
CallerRunsPolicy:提交任务的线程自己去执行该任务 
AbortPolicy:默认的拒绝策略,抛出RejectedExecutionException 
DiscardPolicy:直接丢弃任务,不会抛出任何异常 
DiscardOldestPolicy:丢弃最老的任务,然后把新任务加入到工作队列中 
 
 
 
Executors 
不建议使用Executors,因为Executors提供的很多默认方法使用的是无界队列 LinkedBlockingQueue 
在高负载的情况下,无界队列容易导致OOM ,而OOM会导致所有请求都无法处理 
因此强烈建议使用有界队列  
 
拒绝策略 
使用有界队列 ,当任务过多时,线程池会触发拒绝策略  
线程池默认的拒绝策略会抛出RejectedExecutionException,这是一个运行时异常 ,开发时很容易忽略 
如果线程池处理的任务非常重要,可以自定义拒绝策略 
 
异常处理 
使用ThreadPoolExecutor.execute()方法提交任务时,如果任务在执行过程中出现运行时异常 
 
因此最稳妥的方法还是捕获所有异常 并处理 
 
1 2 3 4 5 6 7 try  {     } catch  (RuntimeException x) {      } catch  (Throwable x) {      } 
参考资料 Java并发编程实战