多執行緒複習筆記之一【關鍵屬性與常用關鍵字概述】
1、併發和並行的區別?
併發可以發生在一個或多個CPU,同時處理多個任務,多個任務之間可以進行切換執行;並行只能發生在多核CPU,一核對應一個任務同時執行
2、執行緒和程序之間的區別?
a) 一個程式至少有一個程序,一個程序至少有個執行緒
b) 程序在執行過程中擁有獨立的記憶體單元,執行緒之間的記憶體卻是共享的
c) 執行緒不能獨立執行,必須依賴程序
舉個例子:
我們執行一個Main方法,裡面其5個執行緒進行列印操作,這是Main方法執行是一個程序,我們可以通過jps看到他的程序Id,但是這一個程序裡面卻有5執行緒在同時執行。
3、實現多執行緒的方式?
public class Test { //此方式不夠靈活,由於Java的單繼承性,不能再繼承其他類了 static class ExtendsThread extends Thread{ @Override public void run() { System.out.println("extends run..."); } } // 推薦這種,java可以實現多個介面,只能繼承一個類 static class RunnableThread implements Runnable{ @Override public void run() { System.out.println("implements run..."); } } public static void main(String[] args) { ExtendsThread thread1 = new ExtendsThread(); thread1.start(); Thread thread2 = new Thread(new RunnableThread()); thread2.start(); } }
4、執行緒的狀態有哪些?
通過Thread類的enum State可以看到
NEW:新建了一個執行緒物件還未呼叫start
RUNNABLE:就緒(ready)和執行中(running)統稱為執行,Running和Runnable可以互相切換,執行緒執行一段時間被另一個高優先順序執行緒搶佔之後從running程式設計Runnable狀態。sleep到時間;IO返回;成功獲得同步監視器;掛起執行緒resume恢復。
BLOCKED:阻塞於鎖;呼叫sleep;阻塞IO;等待通知。
WAITING:執行緒需要等待其他執行緒做出一些通知或中斷動作,例如:呼叫wait()方法,需要等待notify喚醒。
TIMED_WAITING:超時等待,他可以在指定時間後自行返回
TERMINTED:執行緒執行完畢
5、System.out.println原理是?
內部是在synchronized程式碼塊中呼叫OutputStream的write方法
6、執行緒處於準備執行和正在執行Thread.isAlive()返回都是true
7、wait和notify的說明
兩個方法必須都在同步程式碼塊中,並且鎖的物件是同一個,即兩個方法是互斥的,不能同時執行,並且是先執行wait再執行notify,否則執行緒將無限阻塞下去。
如果兩個方法不在同步程式碼塊或者鎖的不是同一個物件將會報java.lang.IllegalMonitorStateException
8、關於Thread.sleep()、Thread.yield()、Thread.join()、wait()的說明
sleep方法並不會釋放鎖,只是釋放CPU的佔用權,睡眠時間到了以後然後和其他執行緒(包括優先順序比當前執行緒高、低的都可以)再競爭CPU佔用權。
yield和sleep類似,只是不能指定睡眠時間,並且執行緒讓步完成之後只能相同優先順序的執行緒可以進行競爭。
join的作用是使呼叫了join先執行完,後面的執行緒才能繼續執行,我們可以傳入等待的時間join(1000),他的底層是使用synchronized,根據執行緒isAlive來進行wait操作,當呼叫join的執行緒執行完畢之後會notify下一個等待的執行緒。
wait是當前執行緒釋放鎖,暫停執行,等待notify(不會立即釋放鎖,需要等待程式碼塊執行完畢)執行緒喚醒,且等待notify執行緒執行完再繼續執行。
9、終止執行緒的幾種方式?
Thread.stop:強制終止,他會終止正在執行的執行緒,不推薦使用,他的底層使用的resume方法。
Thread.suspend:暫停,Thread.resume喚醒;兩個都是獨佔鎖,暫停不推薦使用,暫停之後可以出現數據不同步問題,例如:
一個執行緒執行兩個操作,setName(a),然後執行suspend,導致setAge(10)無法完成賦值。
Thread.interrupt中斷執行緒,他會優雅的停止,如果當前執行緒正在執行,他會等執行緒執行完畢之後再結束,推薦使用。
10、指定執行緒優先順序Thread.setPriority(N); 1<=N<=10,子類和父類的優先順序相同
11、守護執行緒
典型的守護執行緒是垃圾回收執行緒,當程序中沒有使用者執行緒,守護執行緒就沒有存在的必要了。守護執行緒就是一直堅守著使用者執行緒,併為其提供著一些服務。
12、synchronized關鍵字的幾點說明
a) 多個synchronized(this)同一個物件不能併發,多個物件可以併發
b) synchronized(this)與synchronized方法同上
c) synchronized(任意物件)與synchronized方法同上
d) 多個synchronized普通方法同上
e) synchronized方法與synchronized(*.class),同一個物件可以併發,不能物件不能併發
f) 靜態synchronized方法與synchronized(*.class)無論同一個物件還是多個都不能併發執行
g) synchronized(*.class)之間不能併發執行
h) 多個synchronized 靜態方法之間不同同時執行,一個synchronized static方法和一個synchronized非 static方法之間可以同時執行
synchronized具有可重入特性
synchronized裡面程式碼丟擲異常鎖會自動釋放
synchronized不能繼承
synchronized(obj)obj一般不用String型別,容易造成執行緒阻塞
13、volatile關鍵字
當多個執行緒對一個全域性變數進行操作時,每個執行緒會把這個變數從主記憶體拷貝到自己私有CPU快取記憶體中,如果每次都讀主存效率會比較低,因此當一個執行緒修改這個變數時其他執行緒是感覺不到的,就會產生執行緒安全問題,如果使用volatile修飾,當一個執行緒對變數修改時(一旦修改即同步到主存中),另一個執行緒所讀取的變數值會被迫失效,這時候會從新從主存中讀取。