大家都知道:在java中要想實現多線程,有兩種手段,一種是繼續Thread類,另外一種是實現Runable接口。
在繼承Thread:我們在子類中調用的是start()方法,但是實際上調用的還是run()方法的主體。
爲什麼我們不能直接調用run()方法呢?
我的理解是:線程的運行需要本地操作系統的支持
通過實現Runnable接口:
其實Thread中的run方法調用的是Runnable接口的run方法。不知道大家發現沒有,Thread和Runnable都實現了run方法,這種操作模式其實就是代理模式
Thread和Runnable的區別:
如果一個類繼承Thread,則不適合資源共享。但是如果實現了Runable接口的話,則很容易的實現資源共享。
實現Runnable接口比繼承Thread類所具有的優勢:
1):適合多個相同的程序代碼的線程去處理同一個資源
2):可以避免java中的單繼承的限制
3):增加程序的健壯性,代碼可以被多個線程共享,代碼和數據獨立。其實:main方法其實也是一個線程。在java中所以的線程都是同時啓動的,至於什麼時候,哪個先執行,完全看誰先得到CPU的資源。
在java中,每次程序運行至少啓動2個線程。一個是main線程,一個是垃圾收集線程。因爲每當使用java命令執行一個類的時候,實際上都會啓動一個JVM,每一個jVM實習在就是在操作系統中啓動了一個進程。
主線程也有可能在子線程結束之前結束。並且子線程不受影響,不會因爲主線程的結束而結束。
線程的強制執行:join()方法
線程的中斷執行:interrupt();方法
設置爲後臺線程:
demo.setDaemon(
true
);
線程的喚醒:
notify();
線程的睡眠和等待執行:
sleep(
100
);
wait();
我們千萬不要誤以爲優先級越高就先執行。誰先執行還是取決於誰先去的CPU的資源、
線程的禮讓:在線程操作中,也可以使用yield()方法,將一個線程的操作暫時交給其他線程執行。
使用同步:所謂同步就是在統一時間段中只有有一個線程運行,其他的線程必須等到這個線程結束之後才能繼續執行。
【同步代碼塊】:語法格式:
synchronized(同步對象){
//需要同步的代碼
}
但是一般都把當前對象this作爲同步對象。【同步方法】
也可以採用同步方法。
語法格式爲synchronized 方法返回類型方法名(參數列表){
//其他代碼
}當多個線程共享一個資源的時候需要進行同步,但是過多的同步可能導致死鎖
當線程目標run()方法結束時該線程完成。
一旦線程啓動,它就永遠不能再重新啓動。只有一個新的線程可以被啓動,並且只能一次
在一個CPU的機器上上,實際上一次只能運行一個線程。一次只有一個線程棧執行。JVM線程調度程序決定實際運行哪個處於可運行狀態的線程。
衆多可運行線程中的某一個會被選中做爲當前線程。可運行線程被選擇運行的順序是沒有保障的。
一旦線程啓動,它就永遠不能再重新啓動。只有一個新的線程可以被啓動,並且只能一次。