亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

學生視角手把手帶你寫Java?線程池初版

 更新時間:2022年03月21日 11:16:08   作者:摸魚打醬油  
作者是一個來自河源的大三在校生,以下筆記都是作者自學之路的一些淺薄經(jīng)驗,如有錯誤請指正,將來會不斷的完善筆記,幫助更多的Java愛好者入門

Java手寫線程池(第一代)

經(jīng)常使用線程池,故今天突發(fā)奇想,手寫一個線程池,會有很多不足,請多多寬容。因為這也是第一代的版本,后續(xù)會更完善。

手寫線程池-定義參數(shù)

	private final AtomicInteger taskcount=new AtomicInteger(0);
    private final AtomicInteger threadNumber=new AtomicInteger(0);
    private volatile int corePoolSize; 
    private final Set<MyThreadPoolExecutor.MyWorker> workers; 
    private final BlockingQueue<Runnable> waitingQueue; 
    private final String THREADPOOL_NAME="MyThread-Pool-";
    private volatile boolean isRunning=true; 
    private volatile boolean STOPNOW=false; 
    private final ThreadFactory threadFactory; 
  • taskcount:執(zhí)行任務(wù)次數(shù)
  • threadNumber:線程編號,從0開始依次遞增。
  • corePoolSize:核心線程數(shù)
  • workers:工作線程
  • waitingQueue:等待隊列
  • THREADPOOL_NAME:線程名稱
  • isRunning:是否運行
  • STOPNOW:是否立刻停止
  • threadFactory:線程工廠

手寫線程池-構(gòu)造器

    public MyThreadPoolExecutor(int corePoolSize, BlockingQueue<Runnable> waitingQueue,ThreadFactory threadFactory) {
        this.corePoolSize=corePoolSize;
        this.workers=new HashSet<>(corePoolSize);
        this.waitingQueue=waitingQueue;
        this.threadFactory=threadFactory;
        //線程預(yù)熱
        for (int i = 0; i < corePoolSize; i++) {
            new MyWorker();
        }
    }

該構(gòu)造器作用:

1:對參數(shù)進行賦值。

2:線程預(yù)熱。根據(jù)corePoolSize的大小來調(diào)用MyWorker的構(gòu)造器。我們可以看看MyWorker構(gòu)造器做了什么。

	final Thread thread; //為每個MyWorker

        MyWorker(){
            Thread td = threadFactory.newThread(this);
            td.setName(THREADPOOL_NAME+threadNumber.getAndIncrement());
            this.thread=td;
            this.thread.start();
            workers.add(this);
        }
  • MyWorker構(gòu)造器通過線程工廠對當前對象生成Thread;
  • 并設(shè)置線程名為:MyThread-Pool-自增線程編號;
  • 然后調(diào)用線程的start方法啟動線程;
  • 最后存放在workers這個Set集合中,這樣就可以實現(xiàn)線程復(fù)用了。

手寫線程池-默認構(gòu)造器

	public MyThreadPoolExecutor(){
        this(5,new ArrayBlockingQueue<>(10), Executors.defaultThreadFactory());
    }
  • 默認構(gòu)造器的賦初始值:
  • corePoolSize:5
  • waitingQueue:new ArrayBlockingQueue<>(10),長度為10的有限阻塞隊列
  • threadFactory:Executors.defaultThreadFactory()

手寫線程池-execute方法

	public boolean execute(Runnable runnable)
    {
        return waitingQueue.offer(runnable);
    }
  • 本質(zhì)上其實就是把Runnable(任務(wù))放到waitingQueue中。

手寫線程池-處理任務(wù)

	   @Override
        public void run() {
            //循環(huán)接收任務(wù)
                while (true)
                {
                    if((!isRunning&&waitingQueue.size()==0)||STOPNOW)
                    {
                        break;
                    }else {
                        Runnable runnable = waitingQueue.poll();
                        if(runnable!=null){
                            runnable.run();
                            System.out.println("task==>"+taskcount.incrementAndGet());
                        }
                    }
                }
        }

本質(zhì)上就是一個死循環(huán)接收任務(wù),退出條件如下:

  • 優(yōu)雅的退出。當isRunning為false并且waitingQueue的隊列大小為0(也就是無任務(wù)了)
  • 暴力退出。當STOPNOW為true,則說明調(diào)用了shutdownNow方法
  • else語句塊會不斷取任務(wù),當任務(wù)!=null時則調(diào)用run方法處理任務(wù)

手寫線程池-優(yōu)雅關(guān)閉線程池

	public void shutdown()
    {
        this.isRunning=false;
    }

手寫線程池-暴力關(guān)閉線程池

	public void shutdownNow()
    {
        this.STOPNOW=true;
    }

手寫線程池-源代碼

  • 手寫線程池類的源代碼
package com.springframework.concurrent;

import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 線程池類
 * @author 游政杰
 */
public class MyThreadPoolExecutor {

    private final AtomicInteger taskcount=new AtomicInteger(0);//執(zhí)行任務(wù)次數(shù)
    private final AtomicInteger threadNumber=new AtomicInteger(0); //線程編號
    private volatile int corePoolSize; //核心線程數(shù)
    private final Set<MyThreadPoolExecutor.MyWorker> workers; //工作線程
    private final BlockingQueue<Runnable> waitingQueue; //等待隊列
    private final String THREADPOOL_NAME="MyThread-Pool-";//線程名稱
    private volatile boolean isRunning=true; //是否運行
    private volatile boolean STOPNOW=false; //是否立刻停止
    private final ThreadFactory threadFactory; //線程工廠

    public MyThreadPoolExecutor(){
        this(5,new ArrayBlockingQueue<>(10), Executors.defaultThreadFactory());
    }

    public MyThreadPoolExecutor(int corePoolSize, BlockingQueue<Runnable> waitingQueue,ThreadFactory threadFactory) {
        this.corePoolSize=corePoolSize;
        this.workers=new HashSet<>(corePoolSize);
        this.waitingQueue=waitingQueue;
        this.threadFactory=threadFactory;
        //線程預(yù)熱
        for (int i = 0; i < corePoolSize; i++) {
            new MyWorker();
        }
    }

    /**
     * MyWorker就是我們每一個線程對象
     */
    private final class MyWorker implements Runnable{

        final Thread thread; //為每個MyWorker

        MyWorker(){
            Thread td = threadFactory.newThread(this);
            td.setName(THREADPOOL_NAME+threadNumber.getAndIncrement());
            this.thread=td;
            this.thread.start();
            workers.add(this);
        }

        @Override
        public void run() {
            //循環(huán)接收任務(wù)
                while (true)
                {
                    //循環(huán)退出條件:
                    //1:當isRunning為false并且waitingQueue的隊列大小為0(也就是無任務(wù)了),會優(yōu)雅的退出。
                    //2:當STOPNOW為true,則說明調(diào)用了shutdownNow方法進行暴力退出。
                    if((!isRunning&&waitingQueue.size()==0)||STOPNOW)
                    {
                        break;
                    }else {
                        //不斷取任務(wù),當任務(wù)!=null時則調(diào)用run方法處理任務(wù)
                        Runnable runnable = waitingQueue.poll();
                        if(runnable!=null){
                            runnable.run();
                            System.out.println("task==>"+taskcount.incrementAndGet());
                        }
                    }
                }
        }
    }

    public boolean execute(Runnable runnable)
    {
        return waitingQueue.offer(runnable);
    }
    //優(yōu)雅的關(guān)閉
    public void shutdown()
    {
        this.isRunning=false;
    }
    //暴力關(guān)閉
    public void shutdownNow()
    {
        this.STOPNOW=true;
    }
}
  • 測試使用手寫線程池代碼
package com.springframework.test;

import com.springframework.concurrent.MyThreadPoolExecutor;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Executors;

public class ThreadPoolTest {

  public static void main(String[] args) {

    
      MyThreadPoolExecutor myThreadPoolExecutor = new MyThreadPoolExecutor
              (5,new ArrayBlockingQueue<>(6), Executors.defaultThreadFactory());

      for(int i=0;i<10;i++){

          int finalI = i;
          myThreadPoolExecutor.execute(()->{
              System.out.println(Thread.currentThread().getName()+">>>>"+ finalI);
          });

      }

      myThreadPoolExecutor.shutdown();

//      myThreadPoolExecutor.shutdownNow();



  }
}

問題

為什么自定義線程池的execute執(zhí)行的任務(wù)有時會變少?

那是因為waitingQueue滿了放不下任務(wù)了,導致任務(wù)被丟棄,相當于DiscardPolicy拒絕策略

解決辦法有:

1:設(shè)置最大線程數(shù),自動對線程池擴容。

2:調(diào)大waitingQueue的容量capacity

最后:因為這是我手寫的線程池的初代版本,基本實現(xiàn)線程池的復(fù)用功能,然而還有很多未完善,將來會多出幾篇完善后的文章,對目前手寫的線程池進行升級。

后續(xù)還會繼續(xù)出關(guān)于作者手寫Spring框架,手寫Tomcat等等框架的博文?。。。?!

到此這篇關(guān)于學生視角手把手帶你寫Java 線程池的文章就介紹到這了,更多相關(guān)Java 線程池內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java 生成帶Logo和文字的二維碼

    Java 生成帶Logo和文字的二維碼

    這篇文章主要介紹了Java 生成帶Logo和文字的二維碼的方法,幫助大家更好的理解和學習使用Java,感興趣的朋友可以了解下
    2021-04-04
  • java代碼實現(xiàn)mysql分表操作(用戶行為記錄)

    java代碼實現(xiàn)mysql分表操作(用戶行為記錄)

    這篇文章主要介紹了java代碼實現(xiàn)mysql分表操作(用戶行為記錄),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-02-02
  • Java應(yīng)用多機器部署解決大量定時任務(wù)問題

    Java應(yīng)用多機器部署解決大量定時任務(wù)問題

    這篇文章主要介紹了Java應(yīng)用多機器部署解決大量定時任務(wù)問題,兩臺服務(wù)器同時部署了同一套代碼, 代碼中寫有spring自帶的定時任務(wù),但是每次執(zhí)行定時任務(wù)時只需要一臺機器去執(zhí)行,需要的朋友可以參考下
    2019-07-07
  • Java實現(xiàn)圖書館借閱系統(tǒng)

    Java實現(xiàn)圖書館借閱系統(tǒng)

    這篇文章主要為大家詳細介紹了Java實現(xiàn)圖書館借閱系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • Java Fluent Mybatis 分頁查詢與sql日志輸出詳解流程篇

    Java Fluent Mybatis 分頁查詢與sql日志輸出詳解流程篇

    Java中常用的ORM框架主要是mybatis, hibernate, JPA等框架。國內(nèi)又以Mybatis用的多,基于mybatis上的增強框架,又有mybatis plus和TK mybatis等。今天我們介紹一個新的mybatis增強框架 fluent mybatis關(guān)于分頁查詢、sql日志輸出流程
    2021-10-10
  • Java基礎(chǔ)之不簡單的數(shù)組

    Java基礎(chǔ)之不簡單的數(shù)組

    數(shù)組(Array)是有序的元素序列。 若將有限個類型相同的變量的集合命名,那么這個名稱為數(shù)組名。組成數(shù)組的各個變量稱為數(shù)組的分量,也稱為數(shù)組的元素,有時也稱為下標變量
    2021-09-09
  • java、android可用的rtp封包解包h264案例

    java、android可用的rtp封包解包h264案例

    這篇文章主要介紹了java、android可用的rtp封包解包h264案例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-10-10
  • JVM內(nèi)存結(jié)構(gòu)相關(guān)知識解析

    JVM內(nèi)存結(jié)構(gòu)相關(guān)知識解析

    這篇文章主要介紹了JVM內(nèi)存結(jié)構(gòu)相關(guān)知識解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-11-11
  • 使用java實現(xiàn)手機短信驗證全過程

    使用java實現(xiàn)手機短信驗證全過程

    這篇文章主要介紹了使用java實現(xiàn)手機短信驗證全過程,文中有非常詳細的代碼示例,對正在學習java的小伙伴們有非常好的幫助,需要的朋友可以參考下
    2021-04-04
  • Java util.List如何實現(xiàn)列表分段處理

    Java util.List如何實現(xiàn)列表分段處理

    這篇文章主要介紹了Java util.List如何實現(xiàn)列表分段處理,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-09-09

最新評論