java 創建線程的方式
1.繼承 Thread 類實現多線程
- start方法
start()用來啟動一個線程,當調用start方法後,系統才會開啟一個新的線程來執行用戶定義的子任務,在這個過程中,會為相應的線程分配需要的資源。
- run方法
run()方法是不需要用戶來調用的,當通過start方法啟動一個線程之後,當線程獲得了CPU執行時間,便進入run方法體去執行具體的任務。注意,繼承Thread類必須重寫run方法,在run方法中定義具體要執行的任務。
class MyThread extends Thread{
@Override
public void run() {
synchronized (object) {
i++;
System.out.println("i:"+i);
try {
System.out.println("線程"+Thread.currentThread().getName()+"進入睡眠狀態");
Thread.currentThread().sleep(10000);
} catch (InterruptedException e) {
// TODO: handle exception
}
System.out.println("線程"+Thread.currentThread().getName()+"睡眠結束");
i++;
System.out.println("i:"+i);
}
}
}
2.實現 Runnable 接口
只是一個接口,它裡面只有一個run()方法,沒有start()方法。
3.實現 Callable 接口
- Executor 框架中還有一種方法可以實現異步,那就是實現 Callable 接口並重寫call方法。
- 雖然是實現 Callable ,但是在 Executor 實際運行時,會將 Runnable 的實例或 Callable 的實例轉化為 RunnableFuture 的實例。
- RunnableFuture 繼承了 Runnable 和 Future 接口,這點將在下文詳細解釋。瞭解到這些 ,那麼它和 Runnable 有什麼不同呢?
- Callable 與 Runnable 相比不同點:
Callable 可以在任務結束的時候提供一個返回值,Runnable 無法提供這個功能。
Callable 的 call 方法分可以拋出異常,而 Runnable 的 run 方法不能拋出異常。
4.線程池
線程池就是有N個子線程共同在運行的線程組合。
線程池原理
線程池可以減少創建和銷燬線程的次數,從而減少系統資源 的消耗,當一個任務提交到線程池時
- 首先判斷核心線程池中的線程是否已經滿了,如果沒滿,則創建一個核心線 程執行任務,否則進入下一步
- 判斷工作隊列是否已滿,沒有滿則加入工作隊列,否則執行下一步
- 判斷線程數是否達到了最大值,如果不是,則創建非核心線程執行任務,否 則執行飽和策略,默認拋出異常
ThreadPoolExecutor
java.uitl.concurrent.ThreadPoolExecutor類是線程池中最核心的一個類,因此如果要透徹地瞭解Java中的線程池,必須先了解這個類。
- Executor是一個頂層接口,在它裡面只聲明瞭一個方法execute(Runnable),返回值為void,參數為Runnable類型,從字面意思可以理解,就是用來執行傳進去的任務的;
- ExecutorService接口繼承了Executor接口,並聲明瞭一些方法:submit、invokeAll、invokeAny以及shutDown等;
- 抽象類AbstractExecutorService實現了ExecutorService接口,基本實現了ExecutorService中聲明的所有方法。
閱讀更多 天天面試題 的文章