話題一:多線程的3種創(chuàng)建方式
Java使用Thread類代表線程,所有的線程對象都必須是Thread類或其子類的實例。Java可以用三種方式來創(chuàng)建線程,如下所示:
1)繼承Thread類創(chuàng)建線程
2)實現(xiàn)Runnable接口創(chuàng)建線程
3)使用Callable和Future創(chuàng)建線程
話題二:wait和notify的理解與使用
-
案例分析wait和notify
- wait和notify知識補充:首先要理解notify()和wait(),因為這兩個方法本來就不屬于Thread類,而是屬于最底層的object基礎(chǔ)類的,也就是說不光是Thread,每個對象都有notify和wait的功能,為什么?
因為他們是用來操縱鎖的,而每個對象都有鎖,鎖是每個對象的基礎(chǔ),既然鎖是基礎(chǔ)的,那么操縱鎖的方法當(dāng)然也是最基礎(chǔ)了.
話題三:同樣是線程休眠:wait(),sleep(),suspend()有什么區(qū)別呢?
-
wait:讓當(dāng)前線程阻塞,同時又“積極”地等待條件發(fā)生改變,這一點很關(guān)鍵,sleep和suspend無法做到.
1)因為我們有時候需要通過同步(synchronized)的幫助來防止線程之間的沖突,而一旦使用同步,就要鎖定對象,也就是獲取對象鎖,其它要使用該對象鎖的線程都只能排隊等著,等到同步方法或者同步塊里的程序全部運行完才有機會.在同步方法和同步塊中,無論sleep()還是suspend()都不可能自己被調(diào)用的時候解除鎖定,他們都霸占著正在使用的對象鎖不放
2) 而wait卻可以,它可以讓同步方法或者同步塊暫時放棄對象鎖,而將它暫時讓給其它需要對象鎖的人(這里應(yīng)該是程序塊,或線程)用,這意味著可在執(zhí)行wait()期間調(diào)用線程對象中的其他同步方法!在其它情況下(sleep啊,suspend啊),這是不可能的.
3) 但是注意我前面說的,只是暫時放棄對象鎖,暫時給其它線程使用,我wait所在的線程還是要把這個對象鎖收回來的!
sleep:
suspend:
話題四:wait()暫時放棄對象鎖后,如何將對象鎖收回來?
- 第一種方法,限定借出去的時間.在wait()中設(shè)置參數(shù),比如wait(1000),以毫秒為單位,就表明我只借出去1秒中,一秒鐘之后,我自動收回:wait(long timeout);
- 第二種方法,讓借出去的人通知我,他用完了,要還給我了.這時,我馬上就收回來:notify();
- PS:.哎,假如我設(shè)了1小時之后收回,別人只用了半小時就完了,那怎么辦呢?靠!當(dāng)然用完了就收回了,還管我設(shè)的是多長時間啊!
話題五:線程的可用方法展示
- notify():通知
- wait():等待
- run():執(zhí)行
話題六:synchronized和volatile?
1.volatile問題引出
// 老師演示的時候,有一個問題,雖然子線程falg=true,但是main線程打印依然是false!但是在我的JDK上沒有重現(xiàn)這一個現(xiàn)象
public class TestVolatile {
public static void main(String[] args) throws Exception {
// 1.創(chuàng)建一個線程
MyThreadA myThreadA = new MyThreadA();
new Thread(myThreadA).start();
new Thread(myThreadA).start();
// 2.mian主線程
while(true){
if (myThreadA.flag) {
System.out.println("-------------主線程flag:"+myThreadA.flag);
Thread.sleep(1000);
}else{
System.out.println("*************主線程flag:"+myThreadA.flag);
Thread.sleep(1000);
}
}
}
}
class MyThreadA implements Runnable{
public boolean flag = Boolean.FALSE;
@Override
public void run() {
try {
System.out.println("-----------自定義線程執(zhí)行休眠1s");
Thread.sleep(200);
flag = Boolean.TRUE;
System.out.println("-----------休眠結(jié)束flag:"+flag);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
2.synchronized(object){}代表什么含義?
- 只能由一個線程同時使用object
- 多線程時,先判斷鎖,有鎖就要將后續(xù)線程阻塞掛起,直到下一次CPU重新給他進(jìn)行任務(wù)分配
- 加鎖的這種效率是最低的!但是又需要刷新數(shù)據(jù)(內(nèi)存可見性的問題),怎么辦?--volatile
- volatile可以保證多個線程在訪問相同數(shù)據(jù)時候,數(shù)據(jù)是實時可見的(實時將緩存數(shù)據(jù)刷新到主存中)!
3.synchronized和volatile比較
- volatile對比于synchronized,是一種輕量級的同步策略!
- volatile不具備"互斥性",不能保證只有一個線程使用共享數(shù)據(jù)
- volatile不能保證變量的原子性