JAVA基础整理-100.Java 多线编程
Java線程的概念:什么是線程?
Windows 系統是多任務操作系統,它以進程為單位。
系統可以分配給每個進程一段有限的執行 CPU 的時間(也稱為 CPU 時間片
單任務的特點就是排隊執行,也就是同步,就像在 cmd 中輸入一條命令后,必須等待這條命令執行完才可以執行下一條命令一樣。這就是單任務環境的缺點,即 CPU 利用率大幅降低。
圖2 單線程和多線程執行模式 線程可以理解成是在進程中獨立運行的子任務
Java多線程的實現方式
實現多線程編程的方式主要有兩種:一種是繼承 Thread 類,另一種是實現 Runnable 接口。
繼承 Thread 類
使用繼承 Thread 類的方式實現多線程,最大的局限就是不支持多繼承
在使用多線程技術時,代碼的運行結果與代碼執行順序或調用順序是無關的。
除了異步調用之外,同步執行線程 start() 方法的順序不代表線程啟動的順序。
實現 Runnable 接口
如果要創建的線程類已經有一個父類,這時就不能再繼承 Thread 類
提示:從 JDK 的 API 中可以發現,實質上 Thread 類實現了 Runnable 接口,其中的 run() 方法正是對 Runnable 接口中 run() 方法的具體實現。
圖1 使用Runnable接口啟動線程流程
要啟動一個新的線程,不是直接調用 Thread? 子類對象的 run() 方法,而是調用 Thread 子類的 start() 方法
?
兩種方法的比較
1. 繼承 Thread 類的優缺點
而是可以簡單地使用 Threadsleep() 方法,繼承 Thread 類的方式使代碼變得簡單易讀。
2. 實現 Runnable 接口的優缺點
Thread 類是一個虛擬處理機嚴格的封裝,因此只有當處理機模型修改或擴展時,才應該繼承該類。由于 Java 技術只允許單一繼承,因此如果已經繼承了 Thread 類,就不能再繼承其他任何類,這會使用戶只能采用實現 Runnable 接口的方式創建線程。
Java線程的生命周期及線程的幾種狀態
線程也具有生命周期,主要包括 7 種狀態,分別是出生狀態、就緒狀態、運行狀態、等待狀態、休眠狀態、阻塞狀態和死亡狀態,
下面對線程生命周期中的 7 種狀態做說明。
提示:一旦線程進入可執行狀態,它會在就緒狀態與運行狀態下輾轉,同時也可能進入等待狀態、休眠狀態、阻塞狀態或死亡狀態。
Java多線程之間訪問實例變量
當一個線程想要執行同步方法里面的代碼時,線程首先嘗試去拿這把鎖,如果能夠拿到鎖,那么這個線程就可以執行 synchronize 里面的代碼。如果不能拿到鎖,那么這個線程就會不斷地嘗試拿鎖,直到能夠拿到為止,而且有多個線程同時去爭搶這把鎖。
Java非線程安全問題的解決方法
非線程安全主要是指多個線程對同一個對象中的同一個實例變量進行操作時會出現值被更改、值不同步的情況,進而影響程序的執行流程。
使用 synchronized 關鍵字修飾?doPost()?方法,即不允許多個線程同時修改?doPost()?方法中的變量。
Java多線程的同步機制:synchronized
所謂同步機制,指的是兩個線程同時作用在一個對象上,應該保持對象數據的統一性和整體性。Java?提供 synchronized 關鍵字,為防止資源沖突提供了內置支持。共享資源一般是文件、輸入/輸出端口或打印機。
synchronized 不僅可以用到同步方法,也可以用到同步塊。對于同步塊,synchronized 獲取的是參數中的對象鎖。
必須注意的是,Obj 對象的作用范圍不同,控制情況也不盡相同
Java curentThread()方法的作用
從結果可以發現,雖然 this.getName() 方法返回的都是 Thread-0,但是在構造方法中使用的即是 main 線程,而在 run() 方法中使用的是 A 線程。
Java isAlive()方法的作用
isAlive() 方法的作用是判斷當前的線程是否處于活動狀態。
?
Java sleep方法的作用(sleep())
sleep() 方法的作用是在指定的毫秒數內讓當前“正在執行的線程”休眠(暫停執行)
Java getId()方法的作用
getId() 方法的作用非常簡單,就是取得正在運行線程的唯一標識
Java yieId()方法如何使用
yieId() 方法的作用是放棄當前的 CPU 資源,將它讓給其他的任務去占用 CPU 執行時間。
Java停止(終止)線程詳解版
停止一個線程意味著在線程處理完任務之前停掉正在做的操作,也就是放棄當前的操作。
在 Java 中有以下 3 種方法可以終止正在運行的線程:
停止不了的線程
interrupt() 方法的作用是用來停止線程,但 intermpt() 方法的使用效果并不像循環結構中 break 語句那樣,可以馬上停止循環。
?
判斷線程是不是停止狀態
intermpted() 方法具有清除狀態的功能,所以第二次調用 interrupted() 方法返回的值是 false。
異常法停止線程
就可在線程中用 for 語句來判斷線程是否為停止狀態,如果是停止狀態,則后面的代碼不再運行。
在休眠中停止
從運行結果來看,如果在休眠狀態下停止某一線程則會拋出進入 InterruptedException 異常,所以會進入 catch 語句塊清除停止狀態值,使之變成 false。
強制停止線程
調用 stop() 方法可以在任意情況下強制停止一個線程。
注意:調用 stop() 方法時會拋出 java.lang.ThreadDeath 異常,但在通常情況下,此異常不需要顯式地捕捉。
釋放鎖的不良后果
使用 stop() 釋放鎖將會給數據造成不一致性的結果。
使用 return 停止線程
除了上面介紹的方法外,還可以將 intermpt() 方法與 return 結合使用來實現停止線程的效果。
Java暫停/掛起線程(suspend())和恢復線程
(resume())
在?Java?多線程中,可以使用 suspend() 方法暫停線程,使用 resume() 方法恢復線程的執行。
suspend() 與 resume() 方法
從輸出結果的時間來看,調用 suspend() 方法確實可以暫停線程,而在調用 resume() 方法后線程恢復運行狀態。
獨占問題
在使用 suspend() 方法與 resume() 方法時,如果使用不當極易造成公共的同步對象被獨占,從而使得其他線程無法訪問公共同步對象。
不同步問題
在使用 suspend() 方法與 resume() 方法時也容易出現因為線程的暫停而導致數據不同步的情況。
?
Java線程的優先級和執行順序
優先級概述
在 Java 語言中,線程的優先級范圍是 1~10,值必須在 1~10,否則會出現異常;優先級的默認值為 5。優先級較高的線程會被優先執行,當執行完畢,才會輪到優先級較低的線程執行。如果優先級相同,那么就采用輪流執行的方式。
可以使用 Thread 類中的 setPriority() 方法來設置線程的優先級。語法如下:
public final void setPriority(int newPriority)
如果要獲取當前線程的優先級,可以直接調用 getPriority() 方法。語法如下: public final int getPriority();使用優先級
?
轉載于:https://www.cnblogs.com/luojie1216/p/10621318.html
總結
以上是生活随笔為你收集整理的JAVA基础整理-100.Java 多线编程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 架构设计之「服务限流」
- 下一篇: Java多线程——线程的优先级和生命周期