1. 程式人生 > >執行緒 之 執行緒控制

執行緒 之 執行緒控制

下面有幾種方法可以很好的控制執行緒的執行。
1.join 執行緒控制
2.後臺執行緒(守護執行緒)
3.sleep執行緒睡眠
4.yield執行緒讓步

1.join 執行緒控制。
Thread提供了讓一個執行緒等待另外一個執行緒完成的方法-------join()方法
意思:當在a程式執行流(執行緒)中呼叫b執行緒的jion()方法,呼叫者(a)就會被阻塞(出於凍結狀態),直到jion()
執行緒(b)被執行完為止。
jion() 方法經常被使用執行緒的程式呼叫,以將大問題劃分為很多小問題,每個小問題分配一個執行緒,當所有的小問題得到處理後,在呼叫主執行緒來進一步操作。
package myclass;

public class JoinThread extends Thread
{
//提供一個有引數的建構函式,用來設定新執行緒的名字
JoinThread(String name)
{
super(name);
}
//重寫run()方法,定義執行緒執行體
public void run()
{
for(int x=0;x<100;x++)
{
System.out.println(getName() + " " + x);
}
}

public static void main(String[] args)throws Exception //一定要丟擲異常或者Try join(),方法。
{
//啟動一個執行緒
JoinThread st1 = new JoinThread(“新執行緒”);
st1.start();

    for(int x=0;x<100;x++)
    {
         if(x == 20)
         {
               //建立第二個執行緒
              JoinThread st2 = new JoinThread(“被join的執行緒”);
              st2.start();
              //main 執行緒呼叫了st2執行緒的join()方法,
              //main 執行緒必須等待st2執行結束才會向下執行。
              st2.join();
          }
          System.out.println(Thread.currentThread() + "   " + x);
     }
}

}
這個程式一共啟動了三個執行緒,分別為 st2執行緒、st1執行緒、主執行緒。
剛開始,三個執行緒快速切換執行,等到主執行緒執行到x=20時候,主執行緒進入阻塞(凍結)狀態,st1執行緒和st2執行緒進行快速切換執行。直到st2執行緒執行完畢,主執行緒才會執行。
2.後臺執行緒
這種執行緒在後臺執行,主要任務是為其他執行緒提供服務,這種執行緒就是守護執行緒(Daemon Thread).JVM就是最經典的守護執行緒(後臺執行緒)。
後臺執行緒的特徵就是:所有執行緒都死亡時候,後臺執行緒就會自動死亡。
通過setDaemon(true) 方法將執行緒設定成為後臺執行緒。
當整個程式只剩下後臺執行緒時,虛擬機器也會退出,
package myclass;

public class DaemonThread extends Thread
{
//重寫run()方法
public void run()
{
for(int x=0;x<100;x++)
{
System.out.println(getName() + " " + x);
}
}

 public static void main(String[] args)
 {
 //將t執行緒設定成為了守護執行緒。
      DaemonThread t= new DaemonThread();
      t.setDaemon(true);
      t.start();
      for(int x = 0;x <100;x++)
      {
          System.out.println(Thread.currentThread().getName() + "    " + x);
       }
  }

}

在上面的程式中,本來主執行緒和t執行緒都會執行到100,但是將t執行緒設定成為守護執行緒以後,主執行緒是裡面的唯一一個前臺執行緒,當主執行緒結束後,守護執行緒也會自動死亡,虛擬機器退出。(守護執行緒和其他執行緒一樣)

注意:守護執行緒應該在start()方法之前設定。

3.執行緒睡眠
如果想讓當前正在執行的執行緒暫停 一段時間,進入阻塞狀態,則呼叫Thread類中的靜態方法sleep()來說實現。
當前執行緒呼叫sleep()方法後,會進入阻塞狀態,不會或得執行權,因此用sleep()來暫停程式的執行。
package myclass;
public class SleepTest extends Thread//不需要繼承Thread類
{
public static void main(String[] args)throws Exception //需要丟擲異常
{
for(int x=0;x<100;x++)
{
//System.out.println("當前時間為: " + new Date());
//呼叫sleep()方法讓執行緒暫停1s
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName() + " " +x);
}
}
}

4.靜態方法yield ()
它也可以讓正在執行的執行緒暫停,但是不是進入阻塞狀態,而是進入就緒狀態(等待cpu賦給執行權)
當呼叫yield()執行後,只有優先順序和當前優先順序相同或者高於當前優先順序的出於就緒狀態的執行緒會被排程出來執行。

package myclass;

public class YieldTest extends Thread
{
YieldTest(String name)
{
super(name);
}
public void run()
{
for(int x=0;x<100;x++)
{
System.out.println(getName()+ " " + x);
if(x == 20)
Thread.yield();
}
}
public static void main(String[] args)
{
//設定主執行緒的優先順序
Thread.currentThread().setPriority(6);
YieldTest y1 = new YieldTest(“高階”);
//設定該執行緒的優先順序
y1.setPriority(Thread.MAX_PRIORITY);
y1.start();
YieldTest y2 = new YieldTest(“低階”);
y2.setPriority(Thread.MIN_PRIORITY);
y2.start();
}
}

5.執行緒的優先順序:每個執行緒執行都有一定的優先順序,優先順序高的獲取更多的執行權。

在預設的情況下,一般都是5 NORM_PRIORITY
最低位1 MIN_PRIORITY
最高位10 MAX_PRIORITY
Thread類通過setPriority(int newPriority)、getPriority()來設定和返回指定執行緒的優先順序。