1. 程式人生 > >線程池的實現原理

線程池的實現原理

狀態 his color ted except amp bool exc throws

  1 package com.test.ThreadPool;
  2 
  3 import java.util.LinkedList;
  4 import java.util.List;
  5 import java.util.concurrent.atomic.AtomicInteger;
  6 /**
  7  * 線程池的實現原理
  8  * @author Flynn
  9  *
 10  */
 11 public class ThreadPool {
 12     private static ThreadPool pool = null;
 13     
 14     private
final int initNum ; //初始化線程數量 15 private volatile AtomicInteger quenLen = new AtomicInteger(0); //任務隊列長度,volatile修飾的原子操作不必加入同步模塊 16 private List<Runnable> taskQuen = new LinkedList<Runnable>() ; //待處理任務隊列,涉及其的操作要做線程安全處理(使用linkedlist是因為任務隊列插入刪除操作比較頻繁) 17 private workThread[] threads;
18 private ThreadPool(int num){ 19 this.initNum = num ; 20 threads = new workThread[initNum] ; 21 for(int i=0;i<initNum;i++){ 22 threads[i] = new workThread() ; 23 threads[i].start() ; 24 } 25 } 26 /** 27 * 獲取單例 28 *
@param num 29 * @return 30 */ 31 public static ThreadPool getPool(int num){ 32 if(pool == null){ 33 synchronized (ThreadPool.class) { 34 if(pool == null) 35 pool = new ThreadPool(num) ; 36 } 37 } 38 return pool ; 39 } 40 /** 41 * 添加執行任務 42 * @param runs 43 */ 44 public void execute(Runnable...runs){ 45 for(Runnable r : runs){ 46 //操作共享資源任務隊列 需要同步 47 synchronized (taskQuen) { 48 taskQuen.add(r) ; 49 taskQuen.notifyAll() ; 50 } 51 quenLen.incrementAndGet() ; 52 } 53 } 54 public int getTaskNum(){ 55 return quenLen.intValue() ; 56 } 57 public void detory(){ 58 //如果任存在任務,釋放鎖對象並等待20ms再次進入可執行狀態 59 while(!taskQuen.isEmpty()){ 60 try { 61 Thread.sleep(20) ; 62 } catch (InterruptedException e) { 63 // TODO Auto-generated catch block 64 e.printStackTrace(); 65 } 66 } 67 for(int i=0;i<initNum;i++){ 68 threads[i].stopWork() ; 69 threads[i] = null ; //設置為null便於垃圾回收 70 } 71 pool = null ; 72 taskQuen.clear() ; 73 } 74 /** 75 * 內部線程類 76 * @author Flynn 77 * 78 */ 79 private class workThread extends Thread{ 80 private boolean isRunning = true ; //通過此標誌放行線程,也就是說讓線程執行完並銷毀 81 @Override 82 public void run() { 83 // TODO Auto-generated method stub 84 Runnable run = null ; 85 while(isRunning){ 86 synchronized (taskQuen) { 87 //如果沒有任務,釋放鎖對象並等待20ms再次進入可執行狀態 88 while(isRunning && taskQuen.isEmpty()){ 89 try { 90 taskQuen.wait(20) ; 91 } catch (InterruptedException e) { 92 // TODO Auto-generated catch block 93 e.printStackTrace(); 94 } 95 } 96 if(!taskQuen.isEmpty()){ 97 //將任務拿出執行,但不是執行成功如否 98 run = taskQuen.remove(0); 99 quenLen.getAndDecrement(); 100 } 101 } 102 //任務執行,因為沒有涉及到共享資源,不必放入同步模塊 103 if(run!=null){ 104 run.run() ; 105 } 106 run = null ; 107 } 108 } 109 public void stopWork(){ 110 this.isRunning = false ; 111 } 112 } 113 }
 1 package com.test.ThreadPool;
 2 
 3 import java.util.concurrent.atomic.AtomicInteger;
 4 
 5 public class TestMain {
 6 
 7     /**
 8      * @param args
 9      * @throws InterruptedException 
10      */
11     public static void main(String[] args) throws InterruptedException {
12         // TODO Auto-generated method stub
13         ThreadPool pool = ThreadPool.getPool(4) ;
14         new TestMain.myRun() ;
15         pool.execute(new myRun(),new myRun(),new myRun(),new myRun()) ;
16         pool.execute(new myRun(),new myRun(),new myRun(),new myRun()) ;
17         pool.execute(new myRun(),new myRun(),new myRun(),new myRun()) ;
18         pool.execute(new myRun(),new myRun(),new myRun(),new myRun()) ;
19         pool.detory() ;
20     }
21     static class myRun implements Runnable{
22         private static volatile AtomicInteger len = new AtomicInteger(0);    //任務隊列長度,原子操作
23         @Override
24         public void run() {
25             // TODO Auto-generated method stub
26             System.err.println("任務--"+len.incrementAndGet()+"--執行了");
27         }
28     }
29 }

實驗結果:

 1 任務--4--執行了
 2 任務--3--執行了
 3 任務--1--執行了
 4 任務--2--執行了
 5 任務--7--執行了
 6 任務--6--執行了
 7 任務--5--執行了
 8 任務--10--執行了
 9 任務--9--執行了
10 任務--8--執行了
11 任務--13--執行了
12 任務--12--執行了
13 任務--11--執行了
14 任務--16--執行了
15 任務--15--執行了
16 任務--14--執行了

可以看到16個任務全部執行了,沒有重復,但是打印的順序不是遞增的,那是因為workThread的run()中任務的執行沒有放入同步模塊,這也就是只管將任務執行但不控制它具體執行的時間

線程池的實現原理