一、建立線程的方式
1、擴充Thread類
public static class MyThread extends Thread{
@Override
public void run() {
super.run();
System.out.println("I am extends Thread");
}
}
2 繼承runnable
public static class MyRunnable implements Runnable{
@Override
public void run() {
System.out.println("I am implements Runnable");
}
}
3 繼承Callable
public static class MyCallable implements Callable<String>{
@Override
public String call() throws Exception {
System.out.println("I am implements Callable");
return "CallableResult";
}
}
調用:
public static void main(String[] args) throws Exception{
//擴充Thread
MyThread thread = new MyThread();
thread.start();
//繼承Runnable
MyRunnable runnable = new MyRunnable();
new Thread(runnable).start();
//繼承Callable
MyCallable callable = new MyCallable();
FutureTask futureTask = new FutureTask(callable);
new Thread(futureTask).start();
//dosomething
//當調用futureTask.get()方法時主線程會在此處阻塞直到task任務執行完畢,并且會傳回結果。
System.out.println(futureTask.get());
}
二、線程的排程與控制
CPU在某個時刻隻能執行一條指令,線程隻有得到CPU時間片,才能執行指令。JVM負責線程的排程,取得CPU的時間片。優先級高的線程擷取的CPU時間片相對多一些。但優先級高并不代表能獨自占用執行時間片。
Java 作為跨平台語言,線程有 10 個等級。但java線程是通過映射到系統的原生線程上來實作的,是以線程的排程最終還是取決于作業系統,作業系統的優先級與java的優先級并不一一對應。是以優先級高的線程不一定比優先級低的線程優先執行。
三、線程的生命周期
線上程的生命周期中,它要經過建立(New)、就緒(Runnable)、運作(Running)、阻塞(Blocked)和死亡(Dead)5種狀态。
1、建立狀态,當程式使用new關鍵字建立了一個線程之後,該線程就處于建立狀态,此時僅由JVM為其配置設定記憶體,并初始化其成員變量的值
2、就緒狀态,當線程對象調用了start()方法之後,該線程處于就緒狀态。Java虛拟機會為其建立方法調用棧和程式計數器,等待排程運作
3、運作狀态,如果處于就緒狀态的線程獲得了CPU,開始執行run()方法的線程執行體,則該線程處于運作狀态
4、阻塞狀态,當處于運作狀态的線程失去所占用資源之後,便進入阻塞狀态
5、線上程的生命周期當中,線程的各種狀态的轉換過程