最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

java編寫屬于自己的線程池

 更新時間:2018年03月23日 10:24:22   作者:不能說的秘密go  
這篇文章主要為大家詳細(xì)介紹了java編寫屬于自己的線程池,具有一定的參考價值,感興趣的小伙伴們可以參考一下

什么是線程池

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

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

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

線程池的作用:

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

  // 線程池維護工作者線程的最大數(shù)量
  private static final int MAX_WORKER_NUMBERS = 10;
  // 線程池維護工作者線程的默認(rèn)值
  private static final int DEFAULT_WORKER_NUMBERS = 5;
  // 線程池維護工作者線程的最小數(shù)量
  private static final int MIN_WORKER_NUMBERS = 1;
  // 維護一個工作列表,里面加入客戶端發(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ù)線程的"等待/通知機制"這里必須對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 {
    // 表示是否運行該worker
    private volatile boolean running = true;

    public void run() {
      while (running) {
        Job job = null;
        //線程的等待/通知機制
        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(),避免將等待隊列中的線程全部移動到阻塞隊列中而造成資源浪費。

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

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

相關(guān)文章

  • 解決httpServletRequest.getParameter獲取不到參數(shù)的問題

    解決httpServletRequest.getParameter獲取不到參數(shù)的問題

    這篇文章主要介紹了解決httpServletRequest.getParameter獲取不到參數(shù)的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • java實現(xiàn)ssh登錄linux并執(zhí)行命令的三種實現(xiàn)方式

    java實現(xiàn)ssh登錄linux并執(zhí)行命令的三種實現(xiàn)方式

    文章介紹了三種在Java中實現(xiàn)SSH登錄Linux并執(zhí)行命令的方法,包括使用ganymed-ssh2、jsch和sshd-core,由于ganymed-ssh2和jsch的最新版本較舊,可能無法與較新的Linux系統(tǒng)兼容,而sshd-core一直在更新,推薦使用
    2024-11-11
  • 一次 Java 服務(wù)性能優(yōu)化實例詳解

    一次 Java 服務(wù)性能優(yōu)化實例詳解

    這篇文章主要介紹了一次 Java 服務(wù)性能優(yōu)化實例詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-07-07
  • Java代碼塊與代碼加載順序原理詳解

    Java代碼塊與代碼加載順序原理詳解

    這篇文章主要介紹了Java代碼塊與代碼加載順序原理詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-01-01
  • Java中隨機函數(shù)變換的示例詳解

    Java中隨機函數(shù)變換的示例詳解

    這篇文章主要為大家詳細(xì)介紹了Java中隨機函數(shù)的變換,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)Java有一定的幫助,感興趣的可以了解一下
    2022-08-08
  • springboot報錯Invalid?bound?statement?(not?found)的解決

    springboot報錯Invalid?bound?statement?(not?found)的解決

    本文主要介紹了springboot報錯Invalid?bound?statement?(not?found)的解決,遇到這種問題通常是沒有配置好配置文件,下面就來具體介紹一下解決方法,感興趣的可以了解一下
    2025-03-03
  • springmvc+shiro+maven 實現(xiàn)登錄認(rèn)證與權(quán)限授權(quán)管理

    springmvc+shiro+maven 實現(xiàn)登錄認(rèn)證與權(quán)限授權(quán)管理

    Shiro 是一個 Apache 下的一開源項目項目,旨在簡化身份驗證和授權(quán),下面通過實例代碼給大家分享springmvc+shiro+maven 實現(xiàn)登錄認(rèn)證與權(quán)限授權(quán)管理,感興趣的朋友一起看看吧
    2017-09-09
  • Java NIO服務(wù)器端開發(fā)詳解

    Java NIO服務(wù)器端開發(fā)詳解

    這篇文章主要介紹了Java NIO服務(wù)器端開發(fā)詳解,具有一定借鑒價值,需要的朋友可以參考下。
    2017-12-12
  • SpringBoot的HTTPS配置實現(xiàn)

    SpringBoot的HTTPS配置實現(xiàn)

    本文主要介紹了SpringBoot的HTTPS配置實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-04-04
  • 如何將JSP/Servlet項目轉(zhuǎn)換為Spring Boot項目

    如何將JSP/Servlet項目轉(zhuǎn)換為Spring Boot項目

    這篇文章主要介紹了如何將JSP/Servlet項目轉(zhuǎn)換為Spring Boot項目,幫助大家更好的利用springboot進(jìn)行網(wǎng)絡(luò)編程,感興趣的朋友可以了解下
    2020-10-10

最新評論

安乡县| 精河县| 沁水县| 化州市| 内黄县| 大城县| 克拉玛依市| 三穗县| 遵义县| 新安县| 沙田区| 津市市| 星座| 揭西县| 萍乡市| 腾冲县| 三原县| 平邑县| 昭平县| 大兴区| 莱州市| 宁阳县| 蕲春县| 邛崃市| 惠来县| 樟树市| 鄢陵县| 长乐市| 阿克| 沙河市| 景泰县| 清原| 弥勒县| 老河口市| 湖北省| 宣汉县| 榆社县| 名山县| 土默特左旗| 德保县| 综艺|