併發編程基礎三--join線程,後臺線程,線程睡眠,線程讓步,改變線程優先級

Java的線程支持提供了不少便捷方法,如標題. java

1.join線程

join線程的意思就是在當前這個線程A裏,加入另外一個線程B,此時A阻塞,進入就緒狀態,等B完成(結束,線程死亡),A纔會繼續執行. 併發

這個方法一般由使用線程的程序調用,用以將大問題劃分紅許多小問題,每一個小問題配一個線程,但全部小問題處理後,再調用主線程進一步操做. 函數

package org.credo.thread;

public class Thread_join extends Thread{

	public static void main(String[] args) throws InterruptedException {
		new Thread_join("new Thread").start();
		for(int i=0;i<100;i++){
			if(i==20){
				Thread_join thread=new Thread_join("by join's Thread.");
				thread.start();
				//main線程調用了jt線程的join方法,main線程必須等jt執行完才能繼續執行.
				thread.join();
			}
			System.out.println(Thread.currentThread().getName()+" "+i);
		}
	}
	
	//提供一個有參的構造函數,用於設置線程的名字
	public Thread_join(String name){
		super(name);
	}
	
	public void run(){
		for(int i=0;i<100;i++){
			System.out.println(getName()+" "+i);
		}
	}
}
上面是一個示例方法,是main線程調用了jt的join方法.例子能夠直接運行.RUN方法裏不要用這種,會死鎖.

join有3種重載形式: spa

  • 1.join():等待被join的線程執行完成.
  • 2.join(毫秒):等到多少毫秒後再也不等待.若是時間內照舊,超過不等.
  • 3.join(long 毫秒,int 毫微秒):同上.

2.後臺線程

在Java中有一種線程,是在後臺運行,任務是爲其餘線程提供服務,這種線程被稱爲"後臺線程",Daemon Thread,也被叫作"守護線程"或"精靈線程".JVM的垃圾回收線程就是典型的後臺線程.他們有個顯著的特色就是,若是全部的前臺線程都死亡,那麼後臺線程會自動死亡. 線程

調用Thread對象的setDaemon(true)方法可將指定線程設置成後臺線程.下面提供一個DEMO. code

package org.credo.thread;

public class Thread_Daemon extends Thread{

	public static void main(String[] args) {
		Thread_Daemon daemonThread=new Thread_Daemon();
		daemonThread.setDaemon(true);
		daemonThread.start();
		//注意上面的,setDaemon(true)必須在start以前,不然報錯.threadStateException.
		for(int i=0;i<10;i++){
			System.out.println(Thread.currentThread().getName()+" "+i);
		}
	}
	
	public void run(){
		for(int i=0;i<10000;i++){
			System.out.println(getName()+" "+i);
		}
	}
	//能夠發現run方法並不會循環1W次,所以,守護線程在前臺線程全掛了以後也跟着掛了.
}

3.線程睡眠 sleep

路過.........我是打醬油的......javaer都知道吧.......但值得注意的是這是讓線程進入阻塞狀態,而不是就緒狀態. 對象

4.線程讓步 yield

它和sleep不一樣,它讓線程進入的是就緒狀態,它和sleep同樣,是Thread的靜態方法. get

yield()只是讓當前的線程暫停一下,讓系統的線程調度器從新調度一次,徹底可能存在的狀況就是:當某個線程調用了yield()方法暫停以後,線程調度器又將其調度出來從新執行. it

實際上,當某個線程調用了yield()方法暫停後,只有優先級與當前線程相同,或者高的線程纔會有機會執行.以下code: io

package org.credo.thread;

public class Thread_yield extends Thread{

	public static void main(String[] args) {
		//啓動2個併發線程
		Thread_yield ty1=new Thread_yield("Super A--");
		Thread_yield ty2=new Thread_yield("Super B--");
		ty1.start();
		ty2.start();
	}
	
	public Thread_yield(String name){
		super(name);
	}
	
	public void run(){
		for(int i=0;i<50;i++){
			System.out.println(getName()+" "+i);
			if(i==20){
				Thread.yield();
				System.out.println("====================");
			}
		}
	}
}
sleep和yield區別:
  1. sleep暫停當前線程後,會給其餘線程執行機會,不理會優先級.而yield只會給高級,平級.
  2. sleep是將線程轉入阻塞狀態,而yield是就緒狀態.徹底可能說是調用yield後,線程管理調度器再把它扔出去執行.
  3. sleep申明拋出了InterruptedException(中斷異常),而yield木有申明異常.
  4. 建議使用sleep來控制併發線程的執行.Over.

5.改變線程優先級

優先級,高的有多的執行機會.每一個線程的默認優先級都和建立它的父線程優先級相同.默認狀況main線程具備普通優先級.

直接貼代碼了,不想寫字了.

package org.credo.thread;

public class PriorityTest extends Thread{

	//默認爲6.min爲1,中間那個NORM_PRIORITY爲5,max爲6
	public static void main(String[] args) {
		Thread.currentThread().setPriority(6);
		for(int i=0;i<30;i++){
			if(i==10){
				PriorityTest low=new PriorityTest("low");
				low.start();
				System.out.println("建立之初的優先級:"+low.getPriority());
				low.setPriority(MIN_PRIORITY);
			}
			if(i==20){
				PriorityTest high=new PriorityTest("high");
				high.start();
				System.out.println("建立之初的優先級:"+high.getPriority());
				high.setPriority(MAX_PRIORITY);
			}
		}
	}
	
	public PriorityTest(String name){
		super(name);
	}
	
	public void run(){
		for(int i=0;i<50;i++){
			System.out.println(getName()+",優先級是:"+getPriority()+",循環變量的值爲:"+i);
		}
	}
}
通常狀況下使用java指定的3個常量來使用最好.
相關文章
相關標籤/搜索