国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Java > 正文

線程池的原理及java實現(xiàn)

2019-11-06 07:06:10
字體:
供稿:網(wǎng)友

一、線程簡介

創(chuàng)建線程有兩種方式:繼承Thread或?qū)崿F(xiàn)Runnable。Thread實現(xiàn)了Runnable接口,提供了一個空的run()方法,所以不論是繼承Thread還是實現(xiàn)Runnable,都要有自己的run()方法。    一個線程創(chuàng)建后就存在,調(diào)用start()方法就開始運行(執(zhí)行run()方法),調(diào)用wait進入等待或調(diào)用sleep進入休眠期,順利運行完畢或休眠被中斷或運行過程中出現(xiàn)異常而退出。詳見:java創(chuàng)建線程的兩個方法

二、線程池介紹

顧名思義就是事先創(chuàng)建若干個可執(zhí)行的線程放入一個池(容器)中, 需要的時候從池中獲取線程不用自行創(chuàng)建,使用完畢不需要銷毀線程而是放回池中, 從而減少創(chuàng)建和銷毀線程對象的開銷。

 多線程技術(shù)主要解決處理器單元內(nèi)多個線程執(zhí)行的問題,它可以顯著減少處理器單元的閑置時間,增加處理器單元的吞吐能力。        假設(shè)一個服務(wù)器完成一項任務(wù)所需時間為:T1 創(chuàng)建線程時間,T2 在線程中執(zhí)行任務(wù)的時間,T3 銷毀線程時間。    如果:T1 + T3 遠大于 T2,則可以采用線程池,以提高服務(wù)器性能。                一個線程池包括以下四個基本組成部分:                1、線程池管理器(ThreadPool):用于創(chuàng)建并管理線程池,包括 創(chuàng)建線程池,銷毀線程池,添加新任務(wù);                2、工作線程(PoolWorker):線程池中線程,在沒有任務(wù)時處于等待狀態(tài),可以循環(huán)的執(zhí)行任務(wù);                3、任務(wù)接口(Task):每個任務(wù)必須實現(xiàn)的接口,以供工作線程調(diào)度任務(wù)的執(zhí)行,它主要規(guī)定了任務(wù)的入口,任務(wù)執(zhí)行完后的收尾工作,任務(wù)的執(zhí)行狀態(tài)等;                4、任務(wù)隊列(taskQueue):用于存放沒有處理的任務(wù)。提供一種緩沖機制。                    線程池技術(shù)正是關(guān)注如何縮短或調(diào)整T1,T3時間的技術(shù),從而提高服務(wù)器程序性能的。它把T1,T3分別安排在服務(wù)器程序的啟動和結(jié)束的時間段或者一些空閑的時間段,這樣在服務(wù)器程序處理客戶請求時,不會有T1,T3的開銷了。    線程池不僅調(diào)整T1,T3產(chǎn)生的時間段,而且它還顯著減少了創(chuàng)建線程的數(shù)目,看一個例子:    假設(shè)一個服務(wù)器一天要處理50000個請求,并且每個請求需要一個單獨的線程完成。在線程池中,線程數(shù)一般是固定的,所以產(chǎn)生線程總數(shù)不會超過線程池中線程的數(shù)目,而如果服務(wù)器不利用線程池來處理這些請求則線程總數(shù)為50000。一般線程池大小是遠小于50000。所以利用線程池的服務(wù)器程序不會為了創(chuàng)建50000而在處理請求時浪費時間,從而提高效率。

    代碼實現(xiàn)中并沒有實現(xiàn)任務(wù)接口,而是把Runnable對象加入到線程池管理器(ThreadPool),然后剩下的事情就由線程池管理器(ThreadPool)來完成了

三、java實現(xiàn)

實例1、

package TestThread1;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;public class TestThreadPool {	 public static void main(String[] args) {        try{            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));            String s;            ThreadPoolManager manager = new ThreadPoolManager(10);                      while((s = br.readLine()) != null){              manager.PRocess(s);            }        }catch(IOException e){        }	}}
package TestThread1;import java.util.Vector;public class ThreadPoolManager {	private int maxThread;	public Vector vector;	public void setMaxThread(int threadCount){       this.maxThread = threadCount;       	}	       public ThreadPoolManager(int threadCount){        this.setMaxThread(threadCount);        System.out.println("Starting thread pool...");        vector = new Vector();        for(int i=1;i<=10;i++){        	//定義線程            SimpleThread thread = new SimpleThread(i);            vector.addElement(thread);            thread.start();       }   }    public void process(String argument){        int i;        for(i = 0;i<vector.size();i++){            SimpleThread currentThread = (SimpleThread)vector.elementAt(i);                      if(!currentThread.isRunning()){                System.out.println("Thread "+(i+1)+" is processing:"+argument);                currentThread.setArgument(argument);                currentThread.setRunning(true);                return;            }        }              if(i == vector.size()){            System.out.println("pool is full,try in another time.");        }           }}
package TestThread1;public class SimpleThread extends Thread{	private boolean runningFlag;    private String argument;    public boolean isRunning(){        return runningFlag;    }    public synchronized void setRunning(boolean flag){        runningFlag = flag;        if(flag)            this.notify();    }    public String getArgument(){        return this.argument;    }    public void setArgument(String argument){        this.argument = argument;    }        public SimpleThread(int threadNumber){        runningFlag = false;        System.out.println("Thread "+threadNumber+" started.");    }	        public synchronized void run(){        try{            while(true){                if(!runningFlag){                    this.wait();                }else{                    System.out.println("processing "+getArgument()+"...done");                    Thread.sleep(5000);                    System.out.println("Thread is sleeping...");                    setRunning(false);                }            }        }catch(InterruptedException e){            System.out.println("Interrupt");        }    }}結(jié)果:Starting thread pool...Thread 1 started.Thread 2 started.Thread 3 started.Thread 4 started.Thread 5 started.Thread 6 started.Thread 7 started.Thread 8 started.Thread 9 started.Thread 10 started.如輸入:test1Thread 1 is processing:test1processing test1...doneThread is sleeping...如快速輸入:test2     test3test2Thread 1 is processing:test2processing test2...donetest3Thread 2 is processing:test3processing test3...doneThread is sleeping...Thread is sleeping...

實例2、

package TestThread2;//測試線程池 public class TestThreadPool {	public static void main(String[] args) {          // 創(chuàng)建3個線程的線程池          ThreadPool t = ThreadPool.getThreadPool(3);          t.execute(new Runnable[] { new Task(), new Task(), new Task() });          t.execute(new Runnable[] { new Task(), new Task(), new Task() });          System.out.println(t);          t.destroy();// 所有線程都執(zhí)行完成才destory          System.out.println(t);      }        // 任務(wù)類      static class Task implements Runnable {          private static volatile int i = 1;            @Override          public void run() {// 執(zhí)行任務(wù)              System.out.println("任務(wù) " + (i++) + " 完成");          }      }  }
package TestThread2;import java.util.LinkedList;import java.util.List;//線程池類,線程管理器:創(chuàng)建線程,執(zhí)行任務(wù),銷毀線程,獲取線程基本信息 public class ThreadPool {	// 線程池中默認線程的個數(shù)為5      private static int worker_num = 5;      // 工作線程      private WorkThread[] workThrads;      // 未處理的任務(wù)      private static volatile int finished_task = 0;      // 任務(wù)隊列,作為一個緩沖,List線程不安全      private List<Runnable> taskQueue = new LinkedList<Runnable>();      private static ThreadPool threadPool;        // 創(chuàng)建具有默認線程個數(shù)的線程池      private ThreadPool() {          this(5);      }        // 創(chuàng)建線程池,worker_num為線程池中工作線程的個數(shù)      private ThreadPool(int worker_num) {          ThreadPool.worker_num = worker_num;          workThrads = new WorkThread[worker_num];          for (int i = 0; i < worker_num; i++) {              workThrads[i] = new WorkThread();              workThrads[i].start();// 開啟線程池中的線程          }      }        // 單態(tài)模式,獲得一個默認線程個數(shù)的線程池      public static ThreadPool getThreadPool() {          return getThreadPool(ThreadPool.worker_num);      }        // 單態(tài)模式,獲得一個指定線程個數(shù)的線程池,worker_num(>0)為線程池中工作線程的個數(shù)      // worker_num<=0創(chuàng)建默認的工作線程個數(shù)      public static ThreadPool getThreadPool(int worker_num1) {          if (worker_num1 <= 0)              worker_num1 = ThreadPool.worker_num;          if (threadPool == null)              threadPool = new ThreadPool(worker_num1);          return threadPool;      }        // 執(zhí)行任務(wù),其實只是把任務(wù)加入任務(wù)隊列,什么時候執(zhí)行有線程池管理器覺定      public void execute(Runnable task) {          synchronized (taskQueue) {              taskQueue.add(task);              taskQueue.notify();          }      }        // 批量執(zhí)行任務(wù),其實只是把任務(wù)加入任務(wù)隊列,什么時候執(zhí)行有線程池管理器覺定      public void execute(Runnable[] task) {          synchronized (taskQueue) {              for (Runnable t : task)                  taskQueue.add(t);              taskQueue.notify();          }      }        // 批量執(zhí)行任務(wù),其實只是把任務(wù)加入任務(wù)隊列,什么時候執(zhí)行有線程池管理器覺定      public void execute(List<Runnable> task) {          synchronized (taskQueue) {              for (Runnable t : task)                  taskQueue.add(t);              taskQueue.notify();          }      }        // 銷毀線程池,該方法保證在所有任務(wù)都完成的情況下才銷毀所有線程,否則等待任務(wù)完成才銷毀      public void destroy() {          while (!taskQueue.isEmpty()) {// 如果還有任務(wù)沒執(zhí)行完成,就先睡會吧              try {                  Thread.sleep(10);              } catch (InterruptedException e) {                  e.printStackTrace();              }          }          // 工作線程停止工作,且置為null          for (int i = 0; i < worker_num; i++) {              workThrads[i].stopWorker();              workThrads[i] = null;          }          threadPool=null;          taskQueue.clear();// 清空任務(wù)隊列      }        // 返回工作線程的個數(shù)      public int getWorkThreadNumber() {          return worker_num;      }        // 返回已完成任務(wù)的個數(shù),這里的已完成是只出了任務(wù)隊列的任務(wù)個數(shù),可能該任務(wù)并沒有實際執(zhí)行完成      public int getFinishedTasknumber() {          return finished_task;      }        // 返回任務(wù)隊列的長度,即還沒處理的任務(wù)個數(shù)      public int getWaitTasknumber() {          return taskQueue.size();      }        // 覆蓋toString方法,返回線程池信息:工作線程個數(shù)和已完成任務(wù)個數(shù)      @Override      public String toString() {          return "WorkThread number:" + worker_num + "  finished task number:"                  + finished_task + "  wait task number:" + getWaitTasknumber();      }        /**      * 內(nèi)部類,工作線程      */      private class WorkThread extends Thread {          // 該工作線程是否有效,用于結(jié)束該工作線程          private boolean isRunning = true;            /*          * 關(guān)鍵所在啊,如果任務(wù)隊列不空,則取出任務(wù)執(zhí)行,若任務(wù)隊列空,則等待          */          @Override          public void run() {              Runnable r = null;              while (isRunning) {// 注意,若線程無效則自然結(jié)束run方法,該線程就沒用了                  synchronized (taskQueue) {                      while (isRunning && taskQueue.isEmpty()) {// 隊列為空                          try {                              taskQueue.wait(20);                          } catch (InterruptedException e) {                              e.printStackTrace();                          }                      }                      if (!taskQueue.isEmpty())                          r = taskQueue.remove(0);// 取出任務(wù)                  }                  if (r != null) {                      r.run();// 執(zhí)行任務(wù)                  }                  finished_task++;                  r = null;              }          }            // 停止工作,讓該線程自然執(zhí)行完run方法,自然結(jié)束          public void stopWorker() {              isRunning = false;          }      }  }

運行結(jié)果:

WorkThread number:3  finished task number:0  wait task number:6任務(wù) 1 完成任務(wù) 2 完成任務(wù) 3 完成任務(wù) 4 完成任務(wù) 5 完成任務(wù) 6 完成WorkThread number:3  finished task number:6  wait task number:0

分析:由于并沒有任務(wù)接口,傳入的可以是自定義的任何任務(wù),所以線程池并不能準確的判斷該任務(wù)是否真正的已經(jīng)完成(真正完成該任務(wù)是這個任務(wù)的run方法執(zhí)行完畢),只能知道該任務(wù)已經(jīng)出了任務(wù)隊列,正在執(zhí)行或者已經(jīng)完成。

四、線程池適合應(yīng)用的場合

當一個Web服務(wù)器接受到大量短小線程的請求時,使用線程池技術(shù)是非常合適的,它可以大大減少線程的創(chuàng)建和銷毀次數(shù),提高服務(wù)器的工作效率。但如果線程要求的運行時間比較長,此時線程的運行時間比創(chuàng)建時間要長得多,單靠減少創(chuàng)建時間對系統(tǒng)效率的提高不明顯,此時就不適合應(yīng)用線程池技術(shù),需要借助其它的技術(shù)來提高服務(wù)器的服務(wù)效率。

注:如何合理地估算線程池大?。?/p>

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 新余市| 华安县| 肇源县| 安顺市| 阿荣旗| 鄢陵县| 宁波市| 深圳市| 台北县| 西乡县| 景洪市| 洛南县| 衡山县| 龙山县| 横峰县| 昌吉市| 延长县| 吴桥县| 汉源县| 砀山县| 鄂伦春自治旗| 鹤庆县| 文成县| 定日县| 鄂伦春自治旗| 大荔县| 乃东县| 布尔津县| 辉县市| 巫溪县| 太仆寺旗| 丹凤县| 成武县| 安徽省| 清苑县| 资源县| 万源市| 措美县| 云安县| 廉江市| 石渠县|