1. 程式人生 > >Java多執行緒之執行緒排程(二)

Java多執行緒之執行緒排程(二)

(一)執行緒優先順序

執行緒優先順序用1~10表示,10表示優先順序最高,預設值是5.每個優先順序對應一個Thread類的公用靜態常量。如

    public static final int MIN_PRIORITY = 1;
    public static final int NORM_PRIORITY = 5;
    public static final int MAX_PRIORITY = 10;

每個執行緒的優先順序都介於Thread.MIN_PRIORITY和Thread.MAX_PRIORITY之間。

執行緒的優先順序可以通過setPriority(int grade)方法更改,此方法的引數表示要設定的優先順序,必須為1~10的整數。

(二)實現執行緒排程的方法

1,join()方法

使用join方法阻塞執行緒

/**
 * 
 */
package zut.edu.cs.network.practice;

/**
 * @author Administrator
 *
 */
public class MnThread extends Thread {
	String name;

	/**
	 * @param name
	 */
	public MnThread(String name) {
		super();
		this.name = name;
	}
	@Override
	public void run() {
			for(int i=0;i<5;i++) {
				System.out.println(Thread.currentThread().getName()+" "+i);
			}
	}


	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		for(int i=0;i<10;i++) {
			if(i==5) {
				MnThread t1=new MnThread("thead");
				
				try {
					t1.start();
					t1.join();   //把執行緒通過join方法插到主執行緒前面
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			System.out.println(Thread.currentThread().getName()+" "+i);
		}
	}

}

執行結果:

通過join方法實現兩個執行緒之間的資料傳遞

/**
 * 
 */
package zut.edu.cs.network.practice;

/**
 * @author Administrator
 *
 */
public class MnThread extends Thread {
	String value;

	@Override
	public void run() {
	value="value 已經賦值";
	}


	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		MnThread t1=new MnThread();
		t1.start();
		System.out.println("沒呼叫join前:value="+t1.value);
		try {
			t1.join();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println("呼叫join後:value="+t1.value);
	}

}

程式截圖:

2,sleep()方法

使用sleep()方法阻塞執行緒

/**
 * 
 */
package zut.edu.cs.network.practice;

/**
 * @author Administrator
 *
 */
public class MyThread  {

	public static void bySec(long s) {
		for (int i=0;i<s;i++) {
			System.out.println(i+1+"second");
			try {
				Thread.sleep(1000);//睡眠一秒
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		System.out.println("wait");
		MyThread.bySec(5);
		System.out.println("start");
		}

}

程式執行截圖:

3,yield() 方法

yield 的方法可以讓當前程式暫停,允許其他程式執行,但該執行緒仍處於可執行狀態,不變為阻塞狀態。此時,系統選擇優先順序相同或更高的執行緒執行,若無形同或更高的優先順序,則該執行緒繼續執行。

使用yield方法暫停程式

/**
 * 
 */
package zut.edu.cs.network.practice;

/**
 * @author Administrator
 *
 */
public class MnThread extends Thread {
	String name ;

	/**
	 * @param name
	 */
	public MnThread(String name) {
		super();
		this.name = name;
	}





	@Override
	public void run() {
	for(int i=0;i<5;i++) {
		System.out.println(Thread.currentThread().getName()+"第"+i+"次執行");
		Thread.yield();
	}
}


	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		MnThread t1=new MnThread("0");
		t1.start();
		MnThread t2=new MnThread("1");
		t2.start();
	}
}

程式執行截圖

在例子中,呼叫了yield方法之後,當前程式並不是進入了阻塞狀態,而是繼續與其他等待執行的執行緒競爭cpu資源。

sleep() 與yield()方法的區別:

yield和sleep的主要是,yield方法會臨時暫停當前正在執行的執行緒,來讓有同樣優先順序的正在等待的執行緒有機會執行。如果沒有正在等待的執行緒,或者所有正在等待的執行緒的優先順序都比較低,那麼該執行緒會繼續執行。執行了yield方法的執行緒什麼時候會繼續執行由執行緒排程器來決定,不同的廠商可能有不同的行為。yield方法不保證當前的執行緒會暫停或者停止,但是可以保證當前執行緒在呼叫yield方法時會放棄CPU。