今天開始深入學習Java線程,就先從sleep,join,interrupt這3個函數開始吧。
先來看一下這3個函數的功能。
1,sleep:是Thread類的一個靜態方法,作用是讓當前線程阻塞,該函數的參數就是阻塞時間,以毫秒為單位。
2,interrupt:中斷線程。
3,join:作用是讓兩個線程同步。例如:有A,B兩個線程,如果在B中調用了A.join()的話,則表示A線程執行完了才開始執行B線程。
廢話不說了,邊看例子變學習吧。 ========================sleep篇========================
例子所要實現功能:啟動一個線程,每隔一秒鐘執行一次列印
下面看代碼:
package lxcjie;import java.util.Calendar;public class SleepDemo extends Thread { public static void main(String[] args) { //建立線程 SleepDemo sleep = new SleepDemo(); //線程開始執行 sleep.start(); } public void run() { try { //做一個無限迴圈,每一秒輸出一次內容 while (true) { //線程中斷1秒鐘後繼續執行 sleep(1000); System.out.println(getTime() + " " + getName() + " Is Running"); } } catch (InterruptedException e) { e.printStackTrace(); } } //為了更容易理解,在列印內容前面加上目前時間 private String getTime() { Calendar rightNow = Calendar.getInstance(); rightNow.setTimeInMillis(System.currentTimeMillis()); return rightNow.get(Calendar.HOUR) + ":" + rightNow.get(Calendar.MINUTE) + ":" + rightNow.get(Calendar.SECOND); }}
看看執行結果吧:
可以看出,正如我們所期待的,每隔一秒鐘列印了一次內容,OK。 =================interrupt篇=================
例子所要實現功能:列印5次資訊後中斷線程
下面看代碼:
package lxcjie;public class InterruptDemo extends Thread { public static void main(String[] args) throws InterruptedException { //建立線程 InterruptDemo sleep = new InterruptDemo(); //啟動線程 sleep.start(); //主線程中斷5秒鐘 Thread.sleep(5000); //sleep子線程被中斷 sleep.interrupt(); } public void run() { try { //做一個無限迴圈,每一秒列印一條資訊 while (true) { sleep(1000); System.out.println(getName() + " Is Running"); } } catch (InterruptedException e) { //被終端以後列印一條資訊 System.out.println(getName() + " Is Interrupted"); return; } }}
看看執行結果吧:
OK,列印5次資訊後成功被中斷。 ========================join篇========================
sleep和interrupt函數屬於線程中的比較直觀的兩個函數,看例子應該就能理解了。
對於join這個函數,起碼對於我來說,比較抽象,所以下面具體分析一下。
就像前面所說的,join函數的功能就是讓兩個線程保持同步,說白了就是給兩個線程加一個執行順序。
更囉嗦一點,就是說如果不加join函數,A和B兩個線程是同時執行的,加了join函數,A和B兩個線程就按
程式指定的順序依次執行了。
為了驗證,我們先看個例子,看看沒join函數的時候會發生什麼:
package lxcjie;public class JoinDemo { public static void main(String[] args) throws InterruptedException { //建立SleepThread子線程 SleepThread sleep = new SleepThread("MySleepThread"); //建立JoinThread子線程,同時把上面的SleepThread線程作為參數傳入 JoinThread join = new JoinThread("MyJoinThread", sleep); //啟動2個子線程 sleep.start(); join.start(); //主線程中斷3秒鐘 Thread.sleep(3000); //SleepThread子線程被中斷 sleep.interrupt(); }}//建立一個線程類,作用如下://1,每個1秒鐘列印一條資訊//2,如果該線程被中斷,則列印被中斷的資訊class SleepThread extends Thread { public SleepThread(String name) { super(name); } public void run() { while (true) { try { sleep(1000); } catch (InterruptedException e) { System.out.println(">>> " + getName() + " Is Interrupted"); return; } System.out.println(getName() + " Is Running"); } }}//建立另外一個線程類,作用如下://1,調用join函數,與傳入的SleepThread線程保持同步// 也就是說線上程SleepThread執行完畢後,JoinThread才繼續執行//2,每個1秒鐘列印一條資訊//3,如果該線程被中斷,則列印被中斷的資訊class JoinThread extends Thread { private SleepThread sleep = null; //SleepThread作為建構函式的參數,用於線程同步操作 public JoinThread(String name, SleepThread sleep) { super(name); this.sleep = sleep; } public void run() { try { //為了更直觀的理解join函數,我們先把它注釋掉,看看會發生什麼事情 //this.sleep.join(); while (true) { sleep(1000); System.out.println(getName() + " Is Running"); } } catch (InterruptedException e) { System.out.println("Interrupted"); } }}
到底發生什麼了,我們看一下執行結果:
可以看到,兩個線程是同時開始的,MySleepThread線程被中斷後,只剩MyJoinThread線程執行了。
也就是說,兩個線程的執行是完全沒有關係的。
那下面我們把注釋部分去掉:
package lxcjie;public class JoinDemo { public static void main(String[] args) throws InterruptedException { //建立SleepThread子線程 SleepThread sleep = new SleepThread("MySleepThread"); //建立JoinThread子線程,同時把上面的SleepThread線程作為參數傳入 JoinThread join = new JoinThread("MyJoinThread", sleep); //啟動2個子線程 sleep.start(); join.start(); //主線程中斷3秒鐘 Thread.sleep(3000); //SleepThread子線程被中斷 sleep.interrupt(); }}//建立一個線程類,作用如下://1,每個1秒鐘列印一條資訊//2,如果該線程被中斷,則列印被中斷的資訊class SleepThread extends Thread { public SleepThread(String name) { super(name); } public void run() { while (true) { try { sleep(1000); } catch (InterruptedException e) { System.out.println(">>> " + getName() + " Is Interrupted"); return; } System.out.println(getName() + " Is Running"); } }}//建立另外一個線程類,作用如下://1,調用join函數,與傳入的SleepThread線程保持同步// 也就是說線上程SleepThread執行完畢後,JoinThread才繼續執行//2,每個1秒鐘列印一條資訊//3,如果該線程被中斷,則列印被中斷的資訊class JoinThread extends Thread { private SleepThread sleep = null; //SleepThread作為建構函式的參數,用於線程同步操作 public JoinThread(String name, SleepThread sleep) { super(name); this.sleep = sleep; } public void run() { try { //注釋去掉了,看看結果。。 this.sleep.join(); while (true) { sleep(1000); System.out.println(getName() + " Is Running"); } } catch (InterruptedException e) { System.out.println("Interrupted"); } }}
我們再來看看加上join後的結果:
我們看到了什麼。開始的時候只有MySleepThread執行了,等到MySleepThread被中斷後,
MyJoinThread才被執行。看到這裡,join函數的作用就很直觀了。
好了,今天就學習到這裡,順便跟大家分享一下學習結果。
繼續努力學習中。。。