成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Java線程池的四種用法與使用場景

開發 后端
線程池的作用主要是為了提升系統的性能以及使用率。文章剛開始就提到,如果我們使用最簡單的方式創建線程,如果用戶量比較大,那么就會產生很多創建和銷毀線程的動作,這會導致服務器在創建和銷毀線程上消耗的性能可能要比處理實際業務花費的時間和性能更多。

[[280218]]

 一、如下方式存在的問題

  1. new Thread() { 
  2.     @Override 
  3.     public void run() { 
  4.         // 業務邏輯 
  5.     } 
  6. }.start(); 

1、首先頻繁的創建、銷毀對象是一個很消耗性能的事情;2、如果用戶量比較大,導致占用過多的資源,可能會導致我們的服務由于資源不足而宕機;3、綜上所述,在實際的開發中,這種操作其實是不可取的一種方式。

二、使用線程池有什么優點

1、線程池中線程的使用率提升,減少對象的創建、銷毀;2、線程池可以控制線程數,有效的提升服務器的使用資源,避免由于資源不足而發生宕機等問題;

三、線程池的四種使用方式

1、newCachedThreadPool

創建一個線程池,如果線程池中的線程數量過大,它可以有效的回收多余的線程,如果線程數不足,那么它可以創建新的線程。

  1. public static void method() throws Exception { 
  2.  
  3.     ExecutorService executor = Executors.newCachedThreadPool(); 
  4.  
  5.     for (int i = 0; i < 5; i++) { 
  6.  
  7.         final int index = i; 
  8.  
  9.         Thread.sleep(1000); 
  10.  
  11.         executor.execute(new Runnable() { 
  12.             @Override 
  13.             public void run() { 
  14.                 System.out.println(Thread.currentThread().getName() + "  " + index); 
  15.             } 
  16.         }); 
  17.     } 

執行結果

 

通過分析我看可以看到,至始至終都由一個線程執行,實現了線程的復用,并沒有創建多余的線程。如果當我們的業務需要一定的時間進行處理,那么將會出現什么結果。我們來模擬一下。

 

可以明顯的看出,現在就需要幾條線程來交替執行。

不足:這種方式雖然可以根據業務場景自動的擴展線程數來處理我們的業務,但是最多需要多少個線程同時處理缺是我們無法控制的;

優點:如果當第二個任務開始,第一個任務已經執行結束,那么第二個任務會復用第一個任務創建的線程,并不會重新創建新的線程,提高了線程的復用率;

2、newFixedThreadPool

這種方式可以指定線程池中的線程數。舉個栗子,如果一間澡堂子最大只能容納20個人同時洗澡,那么后面來的人只能在外面排隊等待。如果硬往里沖,那么只會出現一種情景,摩擦摩擦...

首先測試一下最大容量為一個線程,那么會不會是我們預測的結果。

  1. public static void method_01() throws InterruptedException { 
  2.  
  3.     ExecutorService executor = Executors.newFixedThreadPool(1); 
  4.  
  5.     for (int i = 0; i < 10; i++) { 
  6.  
  7.         Thread.sleep(1000); 
  8.         final int index = i; 
  9.  
  10.         executor.execute(() -> { 
  11.             try { 
  12.                 Thread.sleep(2 * 1000); 
  13.             } catch (InterruptedException e) { 
  14.                 e.printStackTrace(); 
  15.             } 
  16.             System.out.println(Thread.currentThread().getName() + "  " + index); 
  17.         }); 
  18.     } 
  19.     executor.shutdown(); 

執行結果

 

我們改為3條線程再來看下結果

 

優點:兩個結果綜合說明,newFixedThreadPool的線程數是可以進行控制的,因此我們可以通過控制最大線程來使我們的服務器打到最大的使用率,同事又可以保證及時流量突然增大也不會占用服務器過多的資源。

3、newScheduledThreadPool

該線程池支持定時,以及周期性的任務執行,我們可以延遲任務的執行時間,也可以設置一個周期性的時間讓任務重復執行。 該線程池中有以下兩種延遲的方法。

  • scheduleAtFixedRate

測試一

  1. public static void method_02() { 
  2.     ScheduledExecutorService executor = Executors.newScheduledThreadPool(5); 
  3.  
  4.     executor.scheduleAtFixedRate(new Runnable() { 
  5.         @Override 
  6.         public void run() { 
  7.             long start = new Date().getTime(); 
  8.             System.out.println("scheduleAtFixedRate 開始執行時間:" + 
  9.                     DateFormat.getTimeInstance().format(new Date())); 
  10.             try { 
  11.                 Thread.sleep(5000); 
  12.             } catch (InterruptedException e) { 
  13.                 e.printStackTrace(); 
  14.             } 
  15.             long end = new Date().getTime(); 
  16.             System.out.println("scheduleAtFixedRate 執行花費時間=" + (end - start) / 1000 + "m"); 
  17.             System.out.println("scheduleAtFixedRate 執行完成時間:" + DateFormat.getTimeInstance().format(new Date())); 
  18.             System.out.println("======================================"); 
  19.         } 
  20.     }, 1, 5, TimeUnit.SECONDS); 

執行結果

 

測試二

 

總結:以上兩種方式不同的地方是任務的執行時間,如果間隔時間大于任務的執行時間,任務不受執行時間的影響。如果間隔時間小于任務的執行時間,那么任務執行結束之后,會立馬執行,至此間隔時間就會被打亂。

  • scheduleWithFixedDelay

測試一

  1. public static void method_03() { 
  2.     ScheduledExecutorService executor = Executors.newScheduledThreadPool(2); 
  3.  
  4.     executor.scheduleWithFixedDelay(new Runnable() { 
  5.         @Override 
  6.         public void run() { 
  7.             long start = new Date().getTime(); 
  8.             System.out.println("scheduleWithFixedDelay 開始執行時間:" + 
  9.                     DateFormat.getTimeInstance().format(new Date())); 
  10.             try { 
  11.                 Thread.sleep(1000); 
  12.             } catch (InterruptedException e) { 
  13.                 e.printStackTrace(); 
  14.             } 
  15.             long end = new Date().getTime(); 
  16.             System.out.println("scheduleWithFixedDelay執行花費時間=" + (end - start) / 1000 + "m"); 
  17.             System.out.println("scheduleWithFixedDelay執行完成時間:" 
  18.                     + DateFormat.getTimeInstance().format(new Date())); 
  19.             System.out.println("======================================"); 
  20.         } 
  21.     }, 1, 2, TimeUnit.SECONDS); 

執行結果

 

測試二

  1. public static void method_03() { 
  2.     ScheduledExecutorService executor = Executors.newScheduledThreadPool(2); 
  3.  
  4.     executor.scheduleWithFixedDelay(new Runnable() { 
  5.         @Override 
  6.         public void run() { 
  7.             long start = new Date().getTime(); 
  8.             System.out.println("scheduleWithFixedDelay 開始執行時間:" + 
  9.                     DateFormat.getTimeInstance().format(new Date())); 
  10.             try { 
  11.                 Thread.sleep(5000); 
  12.             } catch (InterruptedException e) { 
  13.                 e.printStackTrace(); 
  14.             } 
  15.             long end = new Date().getTime(); 
  16.             System.out.println("scheduleWithFixedDelay執行花費時間=" + (end - start) / 1000 + "m"); 
  17.             System.out.println("scheduleWithFixedDelay執行完成時間:" 
  18.                     + DateFormat.getTimeInstance().format(new Date())); 
  19.             System.out.println("======================================"); 
  20.         } 
  21.     }, 1, 2, TimeUnit.SECONDS); 

執行結果

 

總結:同樣的,跟scheduleWithFixedDelay測試方法一樣,可以測出scheduleWithFixedDelay的間隔時間不會受任務執行時間長短的影響。

4、newSingleThreadExecutor

這是一個單線程池,至始至終都由一個線程來執行。

  1. public static void method_04() { 
  2.  
  3.     ExecutorService executor = Executors.newSingleThreadExecutor(); 
  4.  
  5.     for (int i = 0; i < 5; i++) { 
  6.         final int index = i; 
  7.         executor.execute(() -> { 
  8.             try { 
  9.                 Thread.sleep(2 * 1000); 
  10.             } catch (InterruptedException e) { 
  11.                 e.printStackTrace(); 
  12.             } 
  13.             System.out.println(Thread.currentThread().getName() + "   " + index); 
  14.         }); 
  15.     } 
  16.     executor.shutdown(); 

執行結果

 

四、線程池的作用

線程池的作用主要是為了提升系統的性能以及使用率。文章剛開始就提到,如果我們使用最簡單的方式創建線程,如果用戶量比較大,那么就會產生很多創建和銷毀線程的動作,這會導致服務器在創建和銷毀線程上消耗的性能可能要比處理實際業務花費的時間和性能更多。線程池就是為了解決這種這種問題而出現的。

同樣思想的設計還有很多,比如數據庫連接池,由于頻繁的連接數據庫,然而創建連接是一個很消耗性能的事情,所有數據庫連接池就出現了。

責任編輯:武曉燕 來源: 程序員的成長
相關推薦

2021-06-06 23:40:53

線程池使用場景

2024-11-27 08:15:50

2015-01-20 10:13:57

OpenStackCephSSD

2020-11-10 10:08:41

Kubernetes容器開發

2020-06-24 07:49:13

Kubernetes場景網絡

2023-10-30 11:40:36

OOM線程池單線程

2017-09-01 11:59:59

Android

2010-08-05 13:44:12

Flex布局

2017-04-17 19:31:03

Android多線程

2019-10-24 07:42:28

Java引用GC

2011-11-24 16:34:39

Java

2018-03-22 15:36:10

大數據智能程序

2010-08-13 13:31:48

Flex效果組件

2010-03-18 17:57:37

Java XMLSoc

2021-08-29 22:05:04

對象自動回收

2009-11-06 14:25:56

WCF接口

2021-03-31 10:05:26

偏向鎖輕量級鎖

2025-06-24 00:00:00

SpringAI提示詞

2022-06-10 08:01:17

ReduxReact

2023-05-16 07:47:18

RabbitMQ消息隊列系統
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 成人夜晚看av | 久久人人爽人人爽 | 国产免费观看一区 | 99精品国产一区二区三区 | 一区二区日韩精品 | 亚洲女人天堂成人av在线 | 亚洲天堂精品一区 | 免费v片在线观看 | 中文字幕精品一区久久久久 | 午夜精品一区二区三区三上悠亚 | 婷婷国产一区 | 午夜精品一区二区三区三上悠亚 | 北条麻妃av一区二区三区 | 欧美白人做受xxxx视频 | 欧美激情一区二区三级高清视频 | 亚洲看片网站 | 天堂色网 | 久久伊人精品 | 日韩在线精品视频 | 久久精品一区 | 欧美日韩在线综合 | 国产在线精品一区二区 | 国产一区二区三区在线免费 | 久久久www成人免费精品 | 亚洲一区二区免费电影 | 自拍偷拍一区二区三区 | 人人爽人人草 | 欧美成人免费在线视频 | 欧美乱操 | 亚洲成人av在线播放 | 精品亚洲国产成av人片传媒 | 日本三级在线视频 | 中文字幕高清视频 | 婷婷综合久久 | 国产高清无av久久 | 一区在线观看视频 | 欧美日韩国产一区二区 | 亚洲国产高清在线观看 | 精品成人一区二区 | 欧美成人一区二区三区 | 亚洲一区久久久 |