Java4Android自學記錄(24-2):java線程的簡單控制方法

道阻且長,行則將至。埋頭苦幹,不鳴則已,一鳴驚人!加油,騷年!

目錄及資源索引

  Java4Android自學過程目錄及資源索引

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 總結

  1. 基本瞭解了線程控制的方法:睡眠線程(sleep),線程讓步(yield),獲取線程優先級,設置線程優先級等;
  2. 整體來說還是遇到了一些問題,踩了一些坑,不過還好啦,慢慢排坑就是啦;
  3. 每天進步一點點,革命尚未成功,同志仍需努力!💪💪💪

如果文章內容有誤,麻煩評論/私信多多指教,謝謝!如果覺得文章內容還不錯,留個讚唄,您的點贊就是對我最大的鼓勵,謝謝您嘞!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章