自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Java線程池的四種用法與使用場(chǎng)景

開發(fā) 后端
線程池的作用主要是為了提升系統(tǒng)的性能以及使用率。文章剛開始就提到,如果我們使用最簡(jiǎn)單的方式創(chuàng)建線程,如果用戶量比較大,那么就會(huì)產(chǎn)生很多創(chuàng)建和銷毀線程的動(dòng)作,這會(huì)導(dǎo)致服務(wù)器在創(chuàng)建和銷毀線程上消耗的性能可能要比處理實(shí)際業(yè)務(wù)花費(fèi)的時(shí)間和性能更多。

[[280218]]

 一、如下方式存在的問(wèn)題

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

1、首先頻繁的創(chuàng)建、銷毀對(duì)象是一個(gè)很消耗性能的事情;2、如果用戶量比較大,導(dǎo)致占用過(guò)多的資源,可能會(huì)導(dǎo)致我們的服務(wù)由于資源不足而宕機(jī);3、綜上所述,在實(shí)際的開發(fā)中,這種操作其實(shí)是不可取的一種方式。

二、使用線程池有什么優(yōu)點(diǎn)

1、線程池中線程的使用率提升,減少對(duì)象的創(chuàng)建、銷毀;2、線程池可以控制線程數(shù),有效的提升服務(wù)器的使用資源,避免由于資源不足而發(fā)生宕機(jī)等問(wèn)題;

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

1、newCachedThreadPool

創(chuàng)建一個(gè)線程池,如果線程池中的線程數(shù)量過(guò)大,它可以有效的回收多余的線程,如果線程數(shù)不足,那么它可以創(chuàng)建新的線程。

  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.     } 

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

 

通過(guò)分析我看可以看到,至始至終都由一個(gè)線程執(zhí)行,實(shí)現(xiàn)了線程的復(fù)用,并沒有創(chuàng)建多余的線程。如果當(dāng)我們的業(yè)務(wù)需要一定的時(shí)間進(jìn)行處理,那么將會(huì)出現(xiàn)什么結(jié)果。我們來(lái)模擬一下。

 

可以明顯的看出,現(xiàn)在就需要幾條線程來(lái)交替執(zhí)行。

不足:這種方式雖然可以根據(jù)業(yè)務(wù)場(chǎng)景自動(dòng)的擴(kuò)展線程數(shù)來(lái)處理我們的業(yè)務(wù),但是最多需要多少個(gè)線程同時(shí)處理缺是我們無(wú)法控制的;

優(yōu)點(diǎn):如果當(dāng)?shù)诙€(gè)任務(wù)開始,第一個(gè)任務(wù)已經(jīng)執(zhí)行結(jié)束,那么第二個(gè)任務(wù)會(huì)復(fù)用第一個(gè)任務(wù)創(chuàng)建的線程,并不會(huì)重新創(chuàng)建新的線程,提高了線程的復(fù)用率;

2、newFixedThreadPool

這種方式可以指定線程池中的線程數(shù)。舉個(gè)栗子,如果一間澡堂子最大只能容納20個(gè)人同時(shí)洗澡,那么后面來(lái)的人只能在外面排隊(duì)等待。如果硬往里沖,那么只會(huì)出現(xiàn)一種情景,摩擦摩擦...

首先測(cè)試一下最大容量為一個(gè)線程,那么會(huì)不會(huì)是我們預(yù)測(cè)的結(jié)果。

  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(); 

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

 

我們改為3條線程再來(lái)看下結(jié)果

 

優(yōu)點(diǎn):兩個(gè)結(jié)果綜合說(shuō)明,newFixedThreadPool的線程數(shù)是可以進(jìn)行控制的,因此我們可以通過(guò)控制最大線程來(lái)使我們的服務(wù)器打到最大的使用率,同事又可以保證及時(shí)流量突然增大也不會(huì)占用服務(wù)器過(guò)多的資源。

3、newScheduledThreadPool

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

  • scheduleAtFixedRate

測(cè)試一

  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 開始執(zhí)行時(shí)間:" + 
  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 執(zhí)行花費(fèi)時(shí)間=" + (end - start) / 1000 + "m"); 
  17.             System.out.println("scheduleAtFixedRate 執(zhí)行完成時(shí)間:" + DateFormat.getTimeInstance().format(new Date())); 
  18.             System.out.println("======================================"); 
  19.         } 
  20.     }, 1, 5, TimeUnit.SECONDS); 

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

 

測(cè)試二

 

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

  • scheduleWithFixedDelay

測(cè)試一

  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 開始執(zhí)行時(shí)間:" + 
  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執(zhí)行花費(fèi)時(shí)間=" + (end - start) / 1000 + "m"); 
  17.             System.out.println("scheduleWithFixedDelay執(zhí)行完成時(shí)間:" 
  18.                     + DateFormat.getTimeInstance().format(new Date())); 
  19.             System.out.println("======================================"); 
  20.         } 
  21.     }, 1, 2, TimeUnit.SECONDS); 

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

 

測(cè)試二

  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 開始執(zhí)行時(shí)間:" + 
  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執(zhí)行花費(fèi)時(shí)間=" + (end - start) / 1000 + "m"); 
  17.             System.out.println("scheduleWithFixedDelay執(zhí)行完成時(shí)間:" 
  18.                     + DateFormat.getTimeInstance().format(new Date())); 
  19.             System.out.println("======================================"); 
  20.         } 
  21.     }, 1, 2, TimeUnit.SECONDS); 

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

 

總結(jié):同樣的,跟scheduleWithFixedDelay測(cè)試方法一樣,可以測(cè)出scheduleWithFixedDelay的間隔時(shí)間不會(huì)受任務(wù)執(zhí)行時(shí)間長(zhǎng)短的影響。

4、newSingleThreadExecutor

這是一個(gè)單線程池,至始至終都由一個(gè)線程來(lái)執(zhí)行。

  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(); 

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

 

四、線程池的作用

線程池的作用主要是為了提升系統(tǒng)的性能以及使用率。文章剛開始就提到,如果我們使用最簡(jiǎn)單的方式創(chuàng)建線程,如果用戶量比較大,那么就會(huì)產(chǎn)生很多創(chuàng)建和銷毀線程的動(dòng)作,這會(huì)導(dǎo)致服務(wù)器在創(chuàng)建和銷毀線程上消耗的性能可能要比處理實(shí)際業(yè)務(wù)花費(fèi)的時(shí)間和性能更多。線程池就是為了解決這種這種問(wèn)題而出現(xiàn)的。

同樣思想的設(shè)計(jì)還有很多,比如數(shù)據(jù)庫(kù)連接池,由于頻繁的連接數(shù)據(jù)庫(kù),然而創(chuàng)建連接是一個(gè)很消耗性能的事情,所有數(shù)據(jù)庫(kù)連接池就出現(xiàn)了。

責(zé)任編輯:武曉燕 來(lái)源: 程序員的成長(zhǎng)
相關(guān)推薦

2024-11-27 08:15:50

2021-06-06 23:40:53

線程池使用場(chǎng)景

2015-01-20 10:13:57

OpenStackCephSSD

2023-10-30 11:40:36

OOM線程池單線程

2020-11-10 10:08:41

Kubernetes容器開發(fā)

2020-06-24 07:49:13

Kubernetes場(chǎng)景網(wǎng)絡(luò)

2017-09-01 11:59:59

Android

2010-08-05 13:44:12

Flex布局

2017-04-17 19:31:03

Android多線程

2018-03-22 15:36:10

大數(shù)據(jù)智能程序

2019-10-24 07:42:28

Java引用GC

2010-08-13 13:31:48

Flex效果組件

2011-11-24 16:34:39

Java

2021-08-29 22:05:04

對(duì)象自動(dòng)回收

2010-03-18 17:57:37

Java XMLSoc

2009-11-06 14:25:56

WCF接口

2021-03-31 10:05:26

偏向鎖輕量級(jí)鎖

2022-06-10 08:01:17

ReduxReact

2023-05-16 07:47:18

RabbitMQ消息隊(duì)列系統(tǒng)

2024-11-04 09:39:08

Java?接口Thread?類
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)