一、線程的創建
java中創建線程有兩種方式:繼承Thread類和實現Runnable接口。
1.繼承Thread類
Java語言中定義了線程類Thread,用戶可以通過繼承Thread類,覆蓋其run()方法創建自己的線程類,線程執行的代碼都包含在run方法中。
public ClassName extends Thread{
public void run(){
}
}
2.實現Runnable接口
另一種線程的實現方式是實現Runnable接口。如果自定義的線程還要繼承其他類,這時就不能采用第一種方式來創建,java語言是不支持多繼承的,卻可以實現多個接口,線程同樣要實現Runnable接口中的run方法,線程需要執行的代碼都包含在run方法中。
Class MyThread implements Runnable{
public void run(){
}
}
二、線程的啟動
繼承Thread類方式的線程啟動非常簡單,只要創建線程類實例後調用其start()方法用來完成線程的啟動。
ClassName c = new ClassName();
c.start();
實現Runnable接口創建的線程首先轉換為Thread類,然後調用Thread類的start()方法啟動線程。
MyThread mt = new MyThread();
Thread t = new Thread(mt);
t.start();
三、線程的生命周期
一個生命周期內的線程主要包括創建、就緒、運行、阻塞和死亡狀態。
1.創建:在線程類使用new關鍵字實例化之後在調用start()方法之前,線程處於創建狀態。處於創建狀態的線程僅僅分配了內存空間,屬於生命周期的初始狀態。
2.就緒:在線程調用了start()方法後即處於就緒狀態。處於就緒狀態的線程具備了除CPU之外運行所需的所有資源。就緒狀態線程排隊等待CPU,由系統調度為其分配。
3.運行:處於就緒狀態的線程獲得CPU之後即處於運行狀態。處於運行狀態的線程才開始正真執行線程run()方法的內容。
4.阻塞:處於運行狀態的線程如果因為某種原因不能繼續執行,則進入阻塞狀態。阻塞狀態與就緒狀態不同的是:就緒狀態只是因為缺少CPU而不能執行,而阻塞狀態是由於各種原因引起線程不能執行,不僅僅是缺少CPU。引起阻塞的原因解除之後,線程再次轉化為就緒狀態。
5.死亡:當線程執行完run()方法的內容或被強制終止時,線程處於死亡狀態,整個生命周期結束。
四、線程的調度
1.線程的優先級:在java語言中,通過調用setPriority()方法為線程設置優先級,優先級用1~10的數字表示,數字越大,優先級越高。如:c.setPriority(1),接著再啟動線程。
2.線程休眠:對於正在執行的線程,可以調用sleep()方法使其放棄CPU進行休眠,此線程轉為阻塞狀態,sleep()方法包含long型的參數,用於指定線程休眠的時間,單位為毫秒。
3.線程讓步:對於正在執行的線程,可以調用yield方法使其重新排隊,將CPU讓給排在後面的線程,此線程轉為就緒狀態。yield()方法只讓步給高優先級或同等優先級的線程。
4.線程等待:對於正在執行的線程,可以調用join()方法等待其結束,然後才執行其他程序。
如:c.start();
c.join();
t.start;
等待c線程執行完成再執行t.
五、線程同步
當多個線程操作同一個共享資源時,比如讀寫同一個變量,存在著資源競爭的問題。為了解決此類問題,需要使用同步機制。在java語言中,利用synchronized關鍵字實現線程同步。
實例如下:
class MyThread implements Runnable{
private int con = 0;
@Override
public void run() {
test();
}
private void test(){
for(int i = 0;i<10;i++){
con++;
Thread.yield();
con--;
System.out.println(con);
}
}
}
public class testThread {
public static void main(String[] args) {
MyThread t = new MyThread();
Thread t1 = new Thread(t);
Thread t2= new Thread(t);
t1.start();
t2.start();
}
}
結果如下:
0
0
0
0
0
0
1
0
0
1
0
1
調整如下:
class MyThread implements Runnable{
private int con = 0;
@Override
public void run() {
test();
}
private synchronized void test(){
for(int i = 0;i<10;i++){
con++;
Thread.yield();
con--;
System.out.println(con);
}
}
}
public class testThread {
public static void main(String[] args) {
MyThread t = new MyThread();
Thread t1 = new Thread(t);
Thread t2= new Thread(t);
t1.start();
t2.start();
}
}
輸出的結果全為0.