今天,我們正在解決一個問題:
同時的,同時的愚蠢的困惑?線程在其生命週期中經歷了什麼?
知識給你解答生活中所有困難的問題。
=concurrent和parallel==
併發是指在一定時間內,多任務交替處理的能力。並行性是指同時處理多個任務的能力。
案例:當一個商場的銷售員需要面對許多顧客時,有些顧客要求價格,有些顧客要求質量。這時,業務員需要不斷地回答客戶,不斷地改變話題,記住前面的話題,以便他回答。這種方式可以理解爲併發的。如果有許多銷售人員對應多個客戶,那麼許多銷售人員可以同時回答客戶的問題。這條路是平行的。
=thread lifetime=
線程是CPU調度和分配的基本單元。線程可以有自己的操作堆棧、程序計數器、本地變量表和其他資源。它與同一進程中的其他線程共享進程的所有資源。
創建線程有三種方法。首先從線程類繼承,如下所示:
第二種方式是實現Runnable接口,如下所示:
public class HandlerThread implements Runnable {
@Override
public void run() {
}
}
建議使用第二種方法,因爲繼承線程類不符合Richter的替換原則。實現可運行的接口可以使編程更加靈活,公開的細節更少。
public class Demo implements Callable<String> {
public static void main(String[] args) throws ExecutionException, InterruptedException {
Callable<String> callable=new Demo();
FutureTask<String> futureTask=new FutureTask<>(callable);
new Thread(futureTask).start();
System.out.println(futureTask.get());
}
@Override
public String call() throws Exception {
return "demo";
}
}
第三種方法使用可調用接口,如下所示:
可調用接口和未來接口的區別在於:
- callable指定call(),runnable指定run()。
- 可調用任務可以在執行後返回值,而可運行任務不能返回值。
- 調用()方法可以引發異常,而run()方法不能引發異常。
- 運行可調用任務將生成一個未來對象,該對象表示異步計算的結果。它提供了一種檢查計算是否已完成、等待計算完成以及檢索計算結果的方法。通過未來的對象,我們可以瞭解任務的性能,取消任務的執行,並獲得任務執行的結果。
- Callable是一個類似於runnable的接口。實現可調用接口的類和實現可運行的類是可以由其他線程執行的任務。
線程有五個生命週期,如下所示:
線程的生命週期狀態爲:新狀態、就緒狀態、運行狀態、阻塞狀態和終止狀態。
- 新建,即新狀態,是指創建線程而不啓動線程的狀態。
- runnable,ready state,是在調用start()方法之後運行之前的狀態。不能多次調用Start(),否則將引發IllegalStateException。
- running,run state是執行run()時線程的狀態。由於某些因素(如時間、異常、鎖、調度等),線程可能會開始運行。
- 阻塞、阻塞狀態,進入此狀態的情況包括:同步阻塞(其他線程佔用的鎖)、活動阻塞(調用線程的某些方法,主動授予CPU執行權限,如sleep()、join()等)和等待阻塞(執行wait()方法)。
- Dead,終止狀態,是運行()執行因異常而結束或退出後的狀態。
我在這裏說的是創建線程的形式。創建線程的本質是實際創建一個可運行的對象(您可以看到相關的源代碼,線程實現可運行的接口,並且只有目標分配是在內部完成的)。在run方法中,仍然執行目標run方法)。線程的start方法是真正的線程創建方法(在內部調用native create square)。爲什麼不建議繼承線程,因爲它向外部世界公開了更多的細節?非常感謝你的想法。