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

Java 線程池詳解

 更新時間:2016年03月26日 09:34:44   作者:趙杰A-124  
本文給大家總結(jié)了java中的線程池的相關(guān)問題,非常的詳細(xì)也很實用,有需要的小伙伴可以參考下。

系統(tǒng)啟動一個線程的成本是比較高的,因為它涉及到與操作系統(tǒng)的交互,使用線程池的好處是提高性能,當(dāng)系統(tǒng)中包含大量并發(fā)的線程時,會導(dǎo)致系統(tǒng)性能劇烈下降,甚至導(dǎo)致JVM崩潰,而線程池的最大線程數(shù)參數(shù)可以控制系統(tǒng)中并發(fā)線程數(shù)不超過次數(shù)。

一、Executors 工廠類用來產(chǎn)生線程池,該工廠類包含以下幾個靜態(tài)工廠方法來創(chuàng)建對應(yīng)的線程池。創(chuàng)建的線程池是一個ExecutorService對象,使用該對象的submit方法或者是execute方法執(zhí)行相應(yīng)的Runnable或者是Callable任務(wù)。線程池本身在不再需要的時候調(diào)用shutdown()方法停止線程池,調(diào)用該方法后,該線程池將不再允許任務(wù)添加進(jìn)來,但是會直到已添加的所有任務(wù)執(zhí)行完成后才死亡。

1、newCachedThreadPool(),創(chuàng)建一個具有緩存功能的線程池,提交到該線程池的任務(wù)(Runnable或Callable對象)創(chuàng)建的線程,如果執(zhí)行完成,會被緩存到CachedThreadPool中,供后面需要執(zhí)行的任務(wù)使用。

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class CacheThreadPool {
  static class Task implements Runnable {
    @Override
    public void run() {
      System.out.println(this + " " + Thread.currentThread().getName() + " AllStackTraces map size: "
          + Thread.currentThread().getAllStackTraces().size());
    }
  }

  public static void main(String[] args) {
    ExecutorService cacheThreadPool = Executors.newCachedThreadPool();
    
    //先添加三個任務(wù)到線程池
    for(int i = 0 ; i < 3; i++) {
      cacheThreadPool.execute(new Task());
    }
    
    //等三個線程執(zhí)行完成后,再次添加三個任務(wù)到線程池
    try {
      Thread.sleep(3000);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
    
    for(int i = 0 ; i < 3; i++) {
      cacheThreadPool.execute(new Task());
    }
  }

}

執(zhí)行結(jié)果如下:

CacheThreadPool$Task@2d312eb9 pool-1-thread-1 AllStackTraces map size: 7
CacheThreadPool$Task@59522b86 pool-1-thread-3 AllStackTraces map size: 7
CacheThreadPool$Task@73dbb89f pool-1-thread-2 AllStackTraces map size: 7
CacheThreadPool$Task@5795cedc pool-1-thread-3 AllStackTraces map size: 7
CacheThreadPool$Task@256d5600 pool-1-thread-1 AllStackTraces map size: 7
CacheThreadPool$Task@7d1c5894 pool-1-thread-2 AllStackTraces map size: 7

線程池中的線程對象進(jìn)行了緩存,當(dāng)有新任務(wù)執(zhí)行時進(jìn)行了復(fù)用。但是如果有特別多的并發(fā)時,緩存線程池還是會創(chuàng)建很多個線程對象。

2、newFixedThreadPool(int nThreads) 創(chuàng)建一個指定線程個數(shù),線程可復(fù)用的線程池。

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class FixedThreadPool {
  static class Task implements Runnable {
    @Override
    public void run() {
      System.out.println(this + " " + Thread.currentThread().getName() + " AllStackTraces map size: "
          + Thread.currentThread().getAllStackTraces().size());
    }
  }

  public static void main(String[] args) {
    ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);

    // 先添加三個任務(wù)到線程池
    for (int i = 0; i < 5; i++) {
      fixedThreadPool.execute(new Task());
    }

    // 等三個線程執(zhí)行完成后,再次添加三個任務(wù)到線程池
    try {
      Thread.sleep(3);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }

    for (int i = 0; i < 3; i++) {
      fixedThreadPool.execute(new Task());
    }
  }

}

執(zhí)行結(jié)果:

FixedThreadPool$Task@7045c12d pool-1-thread-2 AllStackTraces map size: 7
FixedThreadPool$Task@50fa0bef pool-1-thread-2 AllStackTraces map size: 7
FixedThreadPool$Task@ccb1870 pool-1-thread-2 AllStackTraces map size: 7
FixedThreadPool$Task@7392b4e3 pool-1-thread-1 AllStackTraces map size: 7
FixedThreadPool$Task@5bdeff18 pool-1-thread-2 AllStackTraces map size: 7
FixedThreadPool$Task@7d5554e1 pool-1-thread-1 AllStackTraces map size: 7
FixedThreadPool$Task@24468092 pool-1-thread-3 AllStackTraces map size: 7
FixedThreadPool$Task@fa7b978 pool-1-thread-2 AllStackTraces map size: 7

3、newSingleThreadExecutor(),創(chuàng)建一個只有單線程的線程池,相當(dāng)于調(diào)用newFixedThreadPool(1)

4、newSheduledThreadPool(int corePoolSize),創(chuàng)建指定線程數(shù)的線程池,它可以在指定延遲后執(zhí)行線程。也可以以某一周期重復(fù)執(zhí)行某一線程,知道調(diào)用shutdown()關(guān)閉線程池。

示例如下:

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class ScheduledThreadPool {
  static class Task implements Runnable {
    @Override
    public void run() {
      System.out.println("time " + System.currentTimeMillis() + " " + Thread.currentThread().getName() + " AllStackTraces map size: "
          + Thread.currentThread().getAllStackTraces().size());
    }
  }

  public static void main(String[] args) {
    ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(3);
    
    scheduledExecutorService.schedule(new Task(), 3, TimeUnit.SECONDS);
    
    scheduledExecutorService.scheduleAtFixedRate(new Task(), 3, 5, TimeUnit.SECONDS);
  
    try {
      Thread.sleep(30 * 1000);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
    scheduledExecutorService.shutdown();
  }

}

運行結(jié)果如下:

time 1458921795240 pool-1-thread-1 AllStackTraces map size: 6
time 1458921795241 pool-1-thread-2 AllStackTraces map size: 6
time 1458921800240 pool-1-thread-1 AllStackTraces map size: 7
time 1458921805240 pool-1-thread-1 AllStackTraces map size: 7
time 1458921810240 pool-1-thread-1 AllStackTraces map size: 7
time 1458921815240 pool-1-thread-1 AllStackTraces map size: 7
time 1458921820240 pool-1-thread-1 AllStackTraces map size: 7

由運行時間可看出,任務(wù)是按照5秒的周期執(zhí)行的。

5、newSingleThreadScheduledExecutor() 創(chuàng)建一個只有一個線程的線程池,同調(diào)用newScheduledThreadPool(1)。

二、ForkJoinPool和ForkJoinTask

ForkJoinPool是ExecutorService的實現(xiàn)類,支持將一個任務(wù)劃分為多個小任務(wù)并行計算,在把多個小任務(wù)的計算結(jié)果合并成總的計算結(jié)果。它有兩個構(gòu)造函數(shù)

ForkJoinPool(int parallelism)創(chuàng)建一個包含parallelism個并行線程的ForkJoinPool。

ForkJoinPool(),以Runtime.availableProcessors()方法返回值作為parallelism參數(shù)來創(chuàng)建ForkJoinPool。

ForkJoinTask 代表一個可以并行,合并的任務(wù)。它是實現(xiàn)了Future<T>接口的抽象類,它有兩個抽象子類,代表無返回值任務(wù)的RecuriveAction和有返回值的RecursiveTask??筛鶕?jù)具體需求繼承這兩個抽象類實現(xiàn)自己的對象,然后調(diào)用ForkJoinPool的submit 方法執(zhí)行。

RecuriveAction 示例如下,實現(xiàn)并行輸出0-300的數(shù)字。

import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveAction;
import java.util.concurrent.TimeUnit;

public class ActionForkJoinTask {
  static class PrintTask extends RecursiveAction {
    private static final int THRESHOLD = 50;
    private int start;
    private int end;

    public PrintTask(int start, int end) {
      this.start = start;
      this.end = end;
    }

    @Override
    protected void compute() {
      if (end - start < THRESHOLD) {
        for(int i = start; i < end; i++) {
          System.out.println(Thread.currentThread().getName() + " " + i);
        }
      } else {
        int middle = (start + end) / 2;
        PrintTask left = new PrintTask(start, middle);
        PrintTask right = new PrintTask(middle, end);
        left.fork();
        right.fork();
      }
    }

  }

  public static void main(String[] args) {
    ForkJoinPool pool = new ForkJoinPool();
    
    pool.submit(new PrintTask(0, 300));
    try {
      pool.awaitTermination(2, TimeUnit.SECONDS);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
    
    pool.shutdown();
  }

}

在拆分小任務(wù)后,調(diào)用任務(wù)的fork()方法,加入到ForkJoinPool中并行執(zhí)行。

RecursiveTask示例,實現(xiàn)并行計算100個整數(shù)求和。拆分為每20個數(shù)求和后獲取結(jié)果,在最后合并為最后的結(jié)果。

import java.util.Random;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.Future;
import java.util.concurrent.RecursiveTask;

public class TaskForkJoinTask {
  static class CalTask extends RecursiveTask<Integer> {
    private static final int THRESHOLD = 20;

    private int arr[];
    private int start;
    private int end;

    public CalTask(int[] arr, int start, int end) {
      this.arr = arr;
      this.start = start;
      this.end = end;
    }

    @Override
    protected Integer compute() {
      int sum = 0;

      if (end - start < THRESHOLD) {
        for (int i = start; i < end; i++) {
          sum += arr[i];
        }
        System.out.println(Thread.currentThread().getName() + " sum:" + sum);
        return sum;
      } else {
        int middle = (start + end) / 2;
        CalTask left = new CalTask(arr, start, middle);
        CalTask right = new CalTask(arr, middle, end);

        left.fork();
        right.fork();

        return left.join() + right.join();
      }
    }

  }

  public static void main(String[] args) {
    int arr[] = new int[100];
    Random random = new Random();
    int total = 0;

    for (int i = 0; i < arr.length; i++) {
      int tmp = random.nextInt(20);
      total += (arr[i] = tmp);
    }
    System.out.println("total " + total);

    ForkJoinPool pool = new ForkJoinPool(4);

    Future<Integer> future = pool.submit(new CalTask(arr, 0, arr.length));
    try {
      System.out.println("cal result: " + future.get());
    } catch (InterruptedException e) {
      e.printStackTrace();
    } catch (ExecutionException e) {
      e.printStackTrace();
    }
    pool.shutdown();
  }

}

執(zhí)行結(jié)果如下:

total 912
ForkJoinPool-1-worker-2 sum:82
ForkJoinPool-1-worker-2 sum:123
ForkJoinPool-1-worker-2 sum:144
ForkJoinPool-1-worker-3 sum:119
ForkJoinPool-1-worker-2 sum:106
ForkJoinPool-1-worker-2 sum:128
ForkJoinPool-1-worker-2 sum:121
ForkJoinPool-1-worker-3 sum:89
cal result: 912

子任務(wù)執(zhí)行完后,調(diào)用任務(wù)的join()方法獲取子任務(wù)執(zhí)行結(jié)果,再相加獲得最后的結(jié)果。

相關(guān)文章

  • java 網(wǎng)絡(luò)編程之TCP通信和簡單的文件上傳功能實例

    java 網(wǎng)絡(luò)編程之TCP通信和簡單的文件上傳功能實例

    下面小編就為大家分享一篇java 網(wǎng)絡(luò)編程之TCP通信和簡單的文件上傳功能實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-01-01
  • 測量Java對象所占內(nèi)存大小方式

    測量Java對象所占內(nèi)存大小方式

    這篇文章主要介紹了測量Java對象所占內(nèi)存大小方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-09-09
  • JVM內(nèi)存模型/內(nèi)存空間:運行時數(shù)據(jù)區(qū)

    JVM內(nèi)存模型/內(nèi)存空間:運行時數(shù)據(jù)區(qū)

    這篇文章主要介紹了JVM內(nèi)存模型/內(nèi)存空間的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)Java虛擬機(jī),感興趣的朋友可以了解詳細(xì),希望能夠給你帶來幫助
    2021-08-08
  • JAVA+Struts2獲取服務(wù)器地址的方法

    JAVA+Struts2獲取服務(wù)器地址的方法

    這篇文章主要介紹了JAVA+Struts2獲取服務(wù)器地址的方法,是Struts2的一個簡單應(yīng)用,具有一定的借鑒與參考價值,需要的朋友可以參考下
    2014-11-11
  • springboot?vue接口測試HutoolUtil?TreeUtil處理樹形結(jié)構(gòu)

    springboot?vue接口測試HutoolUtil?TreeUtil處理樹形結(jié)構(gòu)

    這篇文章主要介紹了springboot?vue接口測試HutoolUtil?TreeUtil處理樹形結(jié)構(gòu),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-05-05
  • java調(diào)用Hbase報錯解決方法

    java調(diào)用Hbase報錯解決方法

    這篇文章主要為大家介紹了java調(diào)用Hbase報錯解決方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-10-10
  • 使用Spring Cache時設(shè)置緩存鍵的注意事項詳解

    使用Spring Cache時設(shè)置緩存鍵的注意事項詳解

    在現(xiàn)代的Web應(yīng)用中,緩存是提高系統(tǒng)性能和響應(yīng)速度的重要手段之一,Spring框架提供了強(qiáng)大的緩存支持,通過??@Cacheable??、??@CachePut??、??@CacheEvict??等注解可以方便地實現(xiàn)緩存功能,本文給大家介紹了使用Spring Cache時設(shè)置緩存鍵的注意事項
    2025-01-01
  • SpringBoot SSMP 整合案例分享

    SpringBoot SSMP 整合案例分享

    這篇文章主要介紹了SpringBoot SSMP 整合案例分享,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-08-08
  • SpringBoot項目沒有把依賴的jar包一起打包的問題解決

    SpringBoot項目沒有把依賴的jar包一起打包的問題解決

    這篇文章主要介紹了SpringBoot項目沒有把依賴的jar包一起打包的問題解決,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-09-09
  • java實現(xiàn)字符串反轉(zhuǎn)

    java實現(xiàn)字符串反轉(zhuǎn)

    這篇文章主要為大家詳細(xì)介紹了java實現(xiàn)字符串反轉(zhuǎn),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-05-05

最新評論

普洱| 宿迁市| 安龙县| 九江市| 洱源县| 宿州市| 肥城市| 若羌县| 勃利县| 成安县| 南和县| 永吉县| 盐池县| 澜沧| 海原县| 乐昌市| 东兴市| 北海市| 桐庐县| 马公市| 衡南县| 武夷山市| 郎溪县| 丘北县| 明溪县| 自贡市| 海城市| 科尔| 定日县| 葫芦岛市| 峨眉山市| 壤塘县| 湟中县| 交口县| 肇州县| 永修县| 麻城市| 互助| 长阳| 重庆市| 区。|