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

首頁 > 開發(fā) > Java > 正文

java編寫屬于自己的線程池

2024-07-14 08:40:07
字體:
供稿:網(wǎng)友

什么是線程池

線程池就是以一個或多個線程[循環(huán)執(zhí)行]多個應(yīng)用邏輯的線程集合.

一般而言,線程池有以下幾個部分:

完成主要任務(wù)的一個或多個線程.
用于調(diào)度管理的管理線程.
要求執(zhí)行的任務(wù)隊列.

線程池的作用:

線程池作用就是限制系統(tǒng)中執(zhí)行線程的數(shù)量。
根據(jù)系統(tǒng)的環(huán)境情況,可以自動或手動設(shè)置線程數(shù)量,達(dá)到運(yùn)行的最佳效果;少了浪費(fèi)了系統(tǒng)資源,多了造成系統(tǒng)擁擠效率不高。用線程池控制線程數(shù)量,其他線程排隊等候。一個任務(wù)執(zhí)行完畢,再從隊列的中取最前面的任務(wù)開始執(zhí)行。若隊列中沒有等待進(jìn)程,線程池的這一資源處于等待。當(dāng)一個新任務(wù)需要運(yùn)行時,如果線程池中有等待的工作線程,就可以開始運(yùn)行了;否則進(jìn)入等待隊列。

自己實現(xiàn)線程池

根據(jù)如上對線程池的理解,我們自己編寫一個屬于自己的簡單線程池:

簡單的線程池接口:

public interface ThreadPool<Job extends Runnable>{  //執(zhí)行一個任務(wù)(Job),這個Job必須實現(xiàn)Runnable  void execute(Job job); //關(guān)閉線程池 void shutdown(); //增加工作者線程,即用來執(zhí)行任務(wù)的線程 void addWorkers(int num); //減少工作者線程 void removeWorker(int num); //獲取正在等待執(zhí)行的任務(wù)數(shù)量 void getJobSize();}

客戶端可以通過execute(Job)方法將Job提交入線程池來執(zhí)行,客戶端完全不用等待Job的執(zhí)行完成。除了execute(Job)方法以外,線程池接口提供了增加/減少工作者線程以及關(guān)閉線程池的方法。每個客戶端提交的Job都會進(jìn)入到一個工作隊列中等待工作者線程的處理。

線程池接口的默認(rèn)實現(xiàn)

public class DefaultThreadPool<Job extends Runnable> implements ThreadPool<Job>{  // 線程池維護(hù)工作者線程的最大數(shù)量  private static final int MAX_WORKER_NUMBERS = 10;  // 線程池維護(hù)工作者線程的默認(rèn)值  private static final int DEFAULT_WORKER_NUMBERS = 5;  // 線程池維護(hù)工作者線程的最小數(shù)量  private static final int MIN_WORKER_NUMBERS = 1;  // 維護(hù)一個工作列表,里面加入客戶端發(fā)起的工作  private final LinkedList<Job> jobs = new LinkedList<Job>();  // 工作者線程的列表  private final List<Worker> workers = Collections.synchronizedList(new ArrayList<Worker>());  // 工作者線程的數(shù)量  private int workerNum;  // 每個工作者線程編號生成  private AtomicLong threadNum = new AtomicLong(); //生成線程池public DefaultThreadPool() {    this.workerNum = DEFAULT_WORKER_NUMBERS;    initializeWorkers(this.workerNum);  }  public DefaultThreadPool(int num) {    if (num > MAX_WORKER_NUMBERS) {      this.workerNum =DEFAULT_WORKER_NUMBERS;    } else {      this.workerNum = num;    }    initializeWorkers(this.workerNum);  }//初始化每個工作者線程private void initializeWorkers(int num) {    for (int i = 0; i < num; i++) {      Worker worker = new Worker();      //添加到工作者線程的列表      workers.add(worker);      //啟動工作者線程      Thread thread = new Thread(worker);      thread.start();    }  }public void execute(Job job) {    if (job != null) {    //根據(jù)線程的"等待/通知機(jī)制"這里必須對jobs加鎖      synchronized (jobs) {        jobs.addLast(job);        jobs.notify();      }    }  }  //關(guān)閉線程池即關(guān)閉每個工作者線程   public void shutdown() {    for (Worker w : workers) {      w.shutdown();    }  }   //增加工作者線程    public void addWorkers(int num) {    //加鎖,防止該線程還么增加完成而下個線程繼續(xù)增加導(dǎo)致工作者線程超過最大值    synchronized (jobs) {      if (num + this.workerNum > MAX_WORKER_NUMBERS) {        num = MAX_WORKER_NUMBERS - this.workerNum;      }      initializeWorkers(num);      this.workerNum += num;    }  }  //減少工作者線程public void removeWorker(int num) {    synchronized (jobs) {    if(num>=this.workerNum){         throw new IllegalArgumentException("超過了已有的線程數(shù)量");         }      for (int i = 0; i < num; i++) {        Worker worker = workers.get(i);        if (worker != null) {        //關(guān)閉該線程并從列表中移除          worker.shutdown();          workers.remove(i);        }      }      this.workerNum -= num;    }  }public int getJobSize() {    // TODO Auto-generated method stub    return workers.size();  }//定義工作者線程class Worker implements Runnable {    // 表示是否運(yùn)行該worker    private volatile boolean running = true;    public void run() {      while (running) {        Job job = null;        //線程的等待/通知機(jī)制        synchronized (jobs) {          if (jobs.isEmpty()) {            try {              jobs.wait();//線程等待喚醒            } catch (InterruptedException e) {              //感知到外部對該線程的中斷操作,返回              Thread.currentThread().interrupt();              return;            }          }          // 取出一個job          job = jobs.removeFirst();        }        //執(zhí)行job        if (job != null) {          job.run();        }      }    }    // 終止該線程    public void shutdown() {      running = false;    }  }}



從線程池的實現(xiàn)中可以看出,當(dāng)客戶端調(diào)用execute(Job)方法時,會不斷地向任務(wù)列表jobs中添加Job,而每個工作者線程會不讀的從jobs上獲取Job來執(zhí)行,當(dāng)jobs為空時,工作者線程進(jìn)入WAITING狀態(tài)。

當(dāng)添加一個Job后,對工作隊列jobs調(diào)用其notify()方法來喚醒一個工作者線程。此處我們不調(diào)用notifyAll(),避免將等待隊列中的線程全部移動到阻塞隊列中而造成資源浪費(fèi)。

線程池的本質(zhì)就是使用了一個線程安全的工作隊列連接工作者線程和客戶端線程。客戶端線程把任務(wù)放入工作隊列后便返回,而工作者線程則不端的從工作隊列中取出工作并執(zhí)行。當(dāng)工作隊列為空時,工作者線程進(jìn)入WAITING狀態(tài),當(dāng)有客戶端發(fā)送任務(wù)過來后會通過任意一個工作者線程,隨著大量任務(wù)的提交,更多的工作者線程被喚醒。

參考: 《java并發(fā)編程的藝術(shù)》 方騰飛


注:相關(guān)教程知識閱讀請移步到JAVA教程頻道。
發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 土默特右旗| 宁国市| 惠东县| 武陟县| 南昌市| 杭锦后旗| 昌图县| 吐鲁番市| 汕头市| 阳泉市| 汨罗市| 库车县| 达拉特旗| 阿城市| 阆中市| 惠州市| 资源县| 福清市| 个旧市| 黄大仙区| 巴东县| 藁城市| 苏州市| 雅安市| 台中县| 读书| 额尔古纳市| 夏邑县| 江安县| 江城| 宝应县| 宁强县| 陆良县| 白河县| 荃湾区| 南平市| 收藏| 广水市| 内江市| 彩票| 昌乐县|