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

一篇學會Java多線程之線程

開發 后端
我們在學習軟件開發時,多線程,高并發是一個必不可少的知識點,也是在面試時必會問到的內容,為了讓大家對多線程,高并發編程有個清晰認識,特地組織了一個專欄來專門介紹一下,希望能對大家有一些幫助。

本文轉載自微信公眾號「我是開發者FTD」,作者FTD。轉載本文請聯系我是開發者FTD公眾號。

我們在學習軟件開發時,多線程,高并發是一個必不可少的知識點,也是在面試時必會問到的內容,為了讓大家對多線程,高并發編程有個清晰認識,特地組織了一個專欄來專門介紹一下,希望能對大家有一些幫助。

線程簡介

線程是程序運行的基本執行單元。當操作系統(不包括單線程的操作系統,如微軟早期的DOS)在執行一個程序時,會在系統中建立一個進程,而在這個進程中,必須至少建立一個線程(這個線程被稱為主線程)來作為這個程序運行的入口點。因此,在操作系統中運行的任何程序都至少有一個主線程。

進程和線程是現代操作系統中兩個必不可少的運行模型。在操作系統中可以有多個進程,這些進程包括系統進程(由操作系統內部建立的進程)和用戶進程(由用戶程序建立的進程);一個進程中可以有一個或多個線程。進程和進程之間不共享內存,也就是說系統中的進程是在各自獨立的內存空間中運行的。而一個進程中的線可以共享系統分派給這個進程的內存空間。

在進一步介紹之前,我們先來了解一些基本概念,以幫助大家更快速的理解。

基本概念

進程

進程是操作系統中正在執行的不同的應用程序,例如:我們可以同時打開微信和QQ,甚至更多的程序。

在操作系統中運行的程序就是進程,進程就是執行程序的一次執行過程,它是一個動態的概念式系統資源分配的單位

通常在一個進程中可以包含若干個線程,當然一個進程中至少有一個線程,不然沒有存在的意義,線程是CPU調度和執行的單位

線程

線程是一個應用程序進程中不同的執行路徑,例如:我們的WEB服務器,能夠為多個用戶同時提供請求服務。

進程是不活潑的,進程從來不執行任何東西,它只是線程的容器。線程總是在某個進程環境中創建的,而且它的整個生命周期都在該進程中。

在一個進程中,如果創建了多個線程,線程的運行是由調度器安排調度的,調度器是與操作系統緊密相關的,先后順序是不能人為干預的

多線程

多線程擁有多條執行路徑,「主線程與子線程并行交替執行」(普通方法只有主線程一條路徑),對同一份資源操作時,會存在資源搶奪的問題,這時就需要加入并發控制了。

一個Java應用程序,至少有三個線程: main()主線程, gc()垃圾回收線程,異常處理線程。當然如果發生異常,會影響主線程。

多線程程序的優點:

  • 提高應用程序的響應。對圖形化界面更有意義,可增強用戶體驗。同時做多個事情。比如:一邊聽歌、一邊寫代碼。
  • 提高計算機系統CPU的利用率。不過線程也會帶來額外的開銷,如CPU調度時間,并發控制帶來的系統開銷。
  • 改善程序結構。將既長又復雜的進程分為多個線程,獨立運行,利于理解和修改。

何時需要多線程?

程序需要同時執行兩個或多個任務。

需要一些后臺運行的程序時,比如:Java后臺運行的GC線程。

創建線程

Java中創建線程有四種方式,我們下面依次介紹一下。

1、繼承 Thread 類

(1)定義Thread類的子類,并重寫該類的run方法,該run方法的方法體就代表了線程要完成的任務。因此把run()方法稱為執行體。

(2)創建Thread子類的實例對象,即創建了一個線程對象。

(3)調用該線程對象的start()方法來啟動該線程。

示例代碼:

  1. public class MyThread extends Thread { 
  2.  
  3.     // 總票數 
  4.     public int count = 10; 
  5.  
  6.     @Override 
  7.     public void run() { 
  8.         // 當還有票時就繼續售賣 
  9.         while (count > 0) { 
  10.             // 剩余票數 
  11.             count--; 
  12.             System.out.println( 
  13.                     Thread.currentThread().getName() + "售賣第 " + (10 - count) + " 張票,當前剩余票數: " + count); 
  14.         } 
  15.     } 
  16.  
  17.     public static void main(String[] args) { 
  18.         MyThread myThread = new MyThread(); 
  19.         myThread.start(); 
  20.     } 

2、實現Runnable接口

(1)定義Runnable接口的實現類,并重寫該接口的run()方法,該run()方法的方法體同樣是該線程的線程執行體。

(2)創建 Runnable實現類的實例對象,并將該實例作為Thread的target來創建一個Thread對象,該Thread對象才是真正的線程運行對象。

(3)調用該線程對象的start()方法來啟動線程。

示例代碼:

  1. public class MyRunableThread implements Runnable { 
  2.  
  3.     // 總票數 
  4.     public int count = 10; 
  5.  
  6.     @Override 
  7.     public void run() { 
  8.         // 當還有票時就繼續售賣 
  9.         while (count > 0) { 
  10.             // 剩余票數 
  11.             count--; 
  12.             System.out.println( 
  13.                     Thread.currentThread().getName() + "售賣第 " + (10 - count) + " 張票,當前剩余票數: " + count); 
  14.         } 
  15.     } 
  16.  
  17.     public static void main(String[] args) { 
  18.         MyRunableThread myRunableThread = new MyRunableThread(); 
  19.         Thread myThread = new Thread(myRunableThread); 
  20.         myThread.start(); 
  21.     } 

「Thread 和 Runnable 的區別」

上述兩種方法是大家最常見到的兩種創建線程的方法,也常常會被問到兩種方式創建線程的區別,下面簡單總結了一下:

「繼承 Thread 類」

子類繼承 Thread 類具備多線程能力

啟動線程:子類線程對象調用 .start()方法

不建議使用:避免 OOP 單繼承局限性

「實現接口 Runnable」

  • 具有多線程能力
  • 啟動線程:傳入目標對象 + Thread對象調用.start()方法
  • 推薦使用:避免單繼承局限性,方便同一個對象被多個線程使用

另外,在使用線程池時只能放入實現Runable或Callable類線程,不能直接放入繼承Thread的類

3、實現Callable接口

(1)創建Callable接口的實現類,并實現call()方法,該call()方法將作為線程執行體,并且有返回值。

(2)創建Callable實現類的實例,使用FutureTask類來包裝Callable對象,該FutureTask對象封裝了該Callable對象的call()方法的返回值。

(3)使用FutureTask對象作為Thread對象的target創建并啟動新線程。

(4)調用FutureTask對象的get()方法來獲得子線程執行結束后的返回值。

示例代碼:

  1. public class MyCallableThread implements Callable<String> { 
  2.  
  3.     // 總票數 
  4.     private int count = 10; 
  5.  
  6.     @Override 
  7.     public String call() throws Exception { 
  8.         // 當還有票時就繼續售賣 
  9.         while (count > 0) { 
  10.             // 剩余票數 
  11.             count--; 
  12.             System.out.println( 
  13.                     Thread.currentThread().getName() + "售賣第 " + (10 - count) + " 張票,當前剩余票數: " + count); 
  14.         } 
  15.         return "票已售完"
  16.     } 
  17.  
  18.     public static void main(String[] args) throws InterruptedException, ExecutionException { 
  19.         Callable<String> callable = new MyCallableThread(); 
  20.         FutureTask<String> futureTask = new FutureTask<>(callable); 
  21.         Thread myThread = new Thread(futureTask); 
  22.         myThread.start(); 
  23.         // 打印返回結果 
  24.         System.out.println(futureTask.get()); 
  25.     } 

「Runnable和Callable的區別:」

Callable規定的方法是call(),Runnable規定的方法是run()。

Callable的任務執行后可返回值,而Runnable的任務是不能有返回值。

call方法可以拋出異常,run方法不可以。

4、線程池

Java默認提供了五種線程池,通過Executors創建,分別為:

  • 「newCachedThreadPool」 創建一個可緩存線程池,如果線程池長度超過處理需要,可靈活回收空閑線程,若無可回收,則新建線程。
  • 「newFixedThreadPool」 創建一個定長線程池,可控制線程最大并發數,超出的線程會在隊列中等待。
  • 「newScheduledThreadPool」 創建一個定長線程池,支持定時及周期性任務執行。
  • 「newSingleThreadExecutor」 創建一個單線程化的線程池,它只會用唯一的工作線程來執行任務,保證所有任務按照指定順序(FIFO, LIFO, 優先級)執行。
  • 「newWorkStealingPool」 創建一個具有搶占式操作的線程池,由于能夠合理的使用CPU進行對任務操作(并行操作),所以適合使用在很耗時的任務中。

示例代碼:

  1. public class MyThreadPool implements Runnable { 
  2.  
  3.     // 總票數 
  4.     public int count = 10; 
  5.  
  6.     @Override 
  7.     public void run() { 
  8.         // 當還有票時就繼續售賣 
  9.         while (count > 0) { 
  10.             // 剩余票數 
  11.             count--; 
  12.             System.out.println( 
  13.                     Thread.currentThread().getName() + "售賣第 " + (10 - count) + " 張票,當前剩余票數: " + count); 
  14.         } 
  15.     } 
  16.  
  17.     public static void main(String[] args) { 
  18.         ExecutorService ex = Executors.newFixedThreadPool(5); 
  19.         MyThreadPool t = new MyThreadPool(); 
  20.         ex.submit(t); 
  21.         ex.shutdown(); 
  22.     } 

關于線程池,后續會有單獨文章給大家詳細介紹。

 

通過以上的內容,希望大家可以對線程有個初步的認識,相關示例代碼,稍后整理后我會上傳到GitHub上,也請大家留意我們的后續文章。

 

責任編輯:武曉燕 來源: 我是開發者FTD
相關推薦

2021-12-26 18:22:30

Java線程多線程

2021-02-25 15:58:46

C++線程編程開發技術

2021-12-28 09:10:55

Java線程狀態

2019-09-24 14:19:12

PythonC語言文章

2021-03-28 09:12:58

多線程死鎖技術熱點

2021-06-26 16:05:15

內核線程運行

2021-02-15 13:38:38

多線程異步模型

2010-03-16 17:16:38

Java多線程

2010-01-21 11:25:44

linux多線程線程資源

2011-06-22 16:08:40

Qt 多線程 事件循環

2023-01-28 09:50:17

java多線程代碼

2021-03-05 07:38:52

C++線程編程開發技術

2022-01-02 08:43:46

Python

2021-11-30 19:58:51

Java問題排查

2022-03-14 08:16:00

Java程序開發

2016-04-12 09:48:24

nsthread多線程ios

2011-06-22 16:02:37

Qt 多線程 重入

2022-02-07 11:01:23

ZooKeeper

2017-05-27 20:59:30

Java多線程synchronize

2009-03-12 10:52:43

Java線程多線程
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 韩日在线视频 | 亚洲综合第一页 | 91精品国产自产精品男人的天堂 | 国产a区 | 一级毛片,一级毛片 | 一级网站| 欧美二区三区 | 天天玩天天干天天操 | 中文字幕一区二区三区在线观看 | 免费看啪啪网站 | 美国黄色毛片 | 91久久婷婷 | 欧美一区二区三区电影 | 国产不卡在线播放 | 成人亚洲视频 | 亚洲福利一区 | 亚洲一区视频在线播放 | 高清久久久 | 国产又色又爽又黄又免费 | 在线国产一区二区 | 日本精品一区二区 | 国产精品视频久久 | 精品一区二区三区免费视频 | 黄色a级一级片 | 中文字幕一区在线观看视频 | 99久久精品免费看国产小宝寻花 | 国产精品久久久久久妇女6080 | 一区二区三区在线免费观看视频 | 国产成人99久久亚洲综合精品 | 国产视频线观看永久免费 | 天堂一区 | 欧美一区二区三区四区视频 | 亚洲专区在线 | 国产成人精品网站 | 久久国产精品一区二区三区 | 亚洲一区二区三区视频免费观看 | av电影手机版 | 亚洲视频精品在线 | 日韩欧美亚洲 | 亚洲免费网 | 免费午夜剧场 |