進程與線程
進程:
1、進程是指運行中的程序,比如我們使用QQ,就啟動了一個進程,操作系統就會為該進程分配內存空間。當我們使用微信,又啟動了一個進程,操作系統將為其分配新的內存空間。
2、進程是程序的一次執行過程,或是正在運行的一個程序。是一個動態的過程:有它自身的產生、存在和消亡的過程。
線程:
1、線程是由進程創建的,是進程的一個實體。
2、一個進程可以擁有多個線程。
3、分類:? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ???????????????????????????????????????????????????????????? ? ?單線程:同一個時刻,只允許執行一個線程。? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?多線程:同一個時刻,可以執行多個線程。
4、并發與并行
并發:同一個時刻,多個任務交替執行,造成一種“貌似同時”的錯覺,單核CPU就是并發的。
并行:同一個時刻,多個任務同時執行,多核cpu可以實現并行。
注:兩個可以同時存在。
多線程的基本使用
方式一:繼承于?Thread類
步聚:
①創建一個繼承于Threud類的子類
②重寫Thread類的run()
③創建Thread類的子類的對象
④通過此對象調用start()
注:將此線程執行的操作聲明在run()中
start()的作用:
①啟動當前線程?②調用當前線程的run()(run就是一個普通的方法)
注:start()方法調用startO()方法后,該線程并不一定會立馬執行,只是將線程變成了可運行狀態。具體什么時候執行,取決于CPU,由CPU統一調度。
問題:
①不能通過直接調用run()的方式來啟動線程(run方法就是一個普通的方法,沒有真正的啟動一個線程(此時run方法所在的線程就是調用run方法的對象所在的線程,而不是由這個對象單獨開辟出一個新的線程)),而且不會向下執行,直到run執行完成。
public static void main (String [] args){a a = new a();a.run(); //此時所在的線程為main線程a.start(): //此時單獨開辟出一個新的線程
}
class a extends Thread{}
②不可讓已經start()的線程去再啟動一個線程。
③要想重新啟動一個線程,須重新創建一個對象。
注:主線程結束,子線程可能還沒結束,所以進程依舊存在(可在控制臺輸入JConsole監控線程的執行情況)。
方式二:實現Runnable接口
步驟:
①創建一個實現了Runnable 接口的類。
②實現類去重寫Runnable中的抽象方法:run()。
③創建實現類的對象。
④將此對象作為參數傳遞到Thread類的構造器中,創建Thread類的對象(t=new Thread(③中的對象))。
⑤通過Thread類的對象調用start()。(t.start())
Thread類處理Runnable實現類的簡單實現
class MyThread implements Runnable {private Runnable target = null; //屬性,類型是 Runnablepublic MyThread(Runnable target){ //傳入接口實現類,初始化target this.target = target;}@0verridepublic void run() { //動態綁定,調用實現類的run方法if(target != null){target.run();}} public void start() { //調用底層邏輯start0(); }public void start0(){ //真正的實現創建線程,并調用run方法run();}}
方法二和方法一的比較
1、開發中,優先選擇實現 Runnable接口的方式。
2、Runnable實現的方式沒有類的單繼承性的局限性。
3、實現的方式更適合來處理多個線程有共同數據的情況。
4、Thread 本身也實現了Runnable接口。
?