道阻且長,行則將至。埋頭苦幹,不鳴則已,一鳴驚人!加油,騷年!
目錄及資源索引
1 線程的簡單控制方法
1.1 sleep 函數
字面意思很簡單,就是睡眠,結合本文就是讓線程休息一會,跟我們裸機開發常說的延時有點像。
需要注意的是,sleep (結束)之後,不是立馬就進入運行狀態,而是進入就緒狀態,此時就和其他線程在同一起跑線,等待搶佔CPU。
爲什麼這樣做呢?因爲有的時候我們需要讓當前正在執行的線程暫停一段時間,並且進入阻塞狀態,就會用到此方法。
我們嘗試修改之前例程的代碼,增加 sleep 函數如下:
class RunnableImpl implements Runnable
{
public void run()
{
for(int i = 0; i < 100; i++)
{
System.out.println("Runnable-->" + i);
if(50 == i)
{
try
{
Thread.sleep(2000);
}
catch(Exception e)
{
System.out.println(e);
}
}
}
}
}
上述代碼,編譯運行後的結果,對比之前的運行結果,會發現在打印出 50 之後,程序會停止 2s ,然後繼續運行。此時如果在主線程中有打印的話,是不受此 “延時” 影響的。
如果當前線程調用 sleep() 方法進入阻塞狀態,那麼在其睡眠時間段內該線程不會獲得執行機會,即使系統中沒有其他可運行的線程,處於睡眠中的線程也不會運行,因此 sleep() 方法常用來暫停程序的執行。
1.2 yield 函數
使用此函數,此線程會讓出 CPU。讓出之後,還是這麼多線程在一塊搶,但不代表此線程不會去搶 CPU。通俗一點講就跟 復位 差不多,哪一個線程使用這個函數,就回到起點,等待與其他線程一塊賽跑(一塊搶佔 CPU)。
使用 yield() 方法,可以讓當前正在執行的線程暫停,但它不會阻塞該線程,只是將該線程轉入就緒狀態。此方法只是讓當前線程暫停一下,讓系統的線程調度器重新調度。完全可能的情況是:當某個線程調用 yield() 方法暫停之後,線程調度器又將其調度出來重新執行。
實際上當某個線程調用 yield() 方法暫停之後,只有優先級與當前線程相同,或者比當前線程更高的處於就緒狀態的線程纔會獲得執行機會。
1.3 設置線程優先級
線程的優先級用數字表示,範圍爲 1 ~ 10,與線程優先級相關的方法如下
- 查看線程優先級
t.getPriority(); // 查看線程優先級
- 設置線程優先級
t.setPriority(); // 設置線程優先級
- 線程優先級相關宏定義
public final static int MIN_PRIORITY = 1; // 最小優先級
public final static int NORM_PRIORITY = 5; // 默認優先級
public final static int MAX_PRIORITY = 10; // 最大優先級
首先可以使用函數查看當前線程優先級,具體代碼如下:
class Test
{
public static void main(String args[])
{
// 生成一個 Runnable 接口實現類的對象
RunnableImpl ri = new RunnableImpl();
// 生成一個Thread對象,並將Runnable接口實現類的對象作爲
// 參數傳遞給該Thread對象(參數爲Runnable類型的)
Thread t = new Thread(ri);
System.out.println(t.getPriority());
// 通知Thread對象,執行start方法
t.start();
}
}
上述代碼編譯後運行結果如下,可以看到如果沒有設置優先級的話,默認爲 5。
同樣的,我們也可以給線程設置爲最大優先級
class Test
{
public static void main(String args[])
{
// 生成一個 Runnable 接口實現類的對象
RunnableImpl ri = new RunnableImpl();
// 生成一個Thread對象,並將Runnable接口實現類的對象作爲
// 參數傳遞給該Thread對象(參數爲Runnable類型的)
Thread t = new Thread(ri);
t.setPriority(Thread.MAX_PRIORITY);
// 通知Thread對象,執行start方法
t.start();
System.out.println(t.getPriority());
}
}
編譯後運行結果如下:
再次嘗試給線程設置最小優先級,其實只是使用不同的變量而已,代碼如下:
class Test
{
public static void main(String args[])
{
// 生成一個 Runnable 接口實現類的對象
RunnableImpl ri = new RunnableImpl();
// 生成一個Thread對象,並將Runnable接口實現類的對象作爲
// 參數傳遞給該Thread對象(參數爲Runnable類型的)
Thread t = new Thread(ri);
t.setPriority(Thread.MIN_PRIORITY); // 設置最小優先級
// 通知Thread對象,執行start方法
t.start();
System.out.println(t.getPriority());
}
}
編譯後運行結果如下:
簡單總結一下:線程優先級範圍爲 1 ~ 10,最小優先級爲 1 ,最大爲 10 ,默認爲 5 ,可以直接使用 Thread 所提供的靜態常量來設置線程的優先級。
注意:優先級越高的線程,執行的概率就越大,而不是一定就是他先執行;線程能不能運行,關鍵還是看他能不能搶到 CPU 。
2 小插曲
在看書的過程中,書上的最大優先級是 1 ,我是懵逼的,後來去請教了一下,果然是書本上的弄錯了。
這個是書本上的定義
這個是我參考別人的方法,也去找了一下 JDK 中的源碼,發現還真是書本上的錯了,唉,心累
3 總結
- 基本瞭解了線程控制的方法:睡眠線程(sleep),線程讓步(yield),獲取線程優先級,設置線程優先級等;
- 整體來說還是遇到了一些問題,踩了一些坑,不過還好啦,慢慢排坑就是啦;
- 每天進步一點點,革命尚未成功,同志仍需努力!💪💪💪
如果文章內容有誤,麻煩評論/私信多多指教,謝謝!如果覺得文章內容還不錯,留個讚唄,您的點贊就是對我最大的鼓勵,謝謝您嘞!