join()方法的使用

1.join()方法介紹java

join():使所屬的線程對象x正常執行run()方法中的任務,而使當前線程z進行無限期的阻塞,等待線程x銷燬後再繼續執行z後面的代碼。dom

join(long):等待必定時間。ide

  • 在join過程當中,若是當前線程被中斷,則當前線程出現異常,但join所屬的線程繼續運行。
  • join()在內部使用wait()方法進行等待,因此會釋放鎖
package chapter3.join;

public class MyThread extends Thread{
	
	@Override
	public void run() {
		super.run();
		try {
			int secondValue = (int) (Math.random()*10000);
			System.out.println(secondValue);
			Thread.sleep(secondValue);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}

package chapter3.join;

public class Test {

    public static void main(String[] args) {
        try {
            MyThread myThread = new MyThread();
            myThread.start();
            myThread.join();
            System.out.println("MyThread 執行完以後執行!");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

運行結果:this

9574
MyThread 執行完以後執行!線程

2.join()方法後面的代碼提早運行對象

join()方法源碼:blog

//不帶參數
public final void join() throws InterruptedException {
     join(0);
}
//帶參數
public final synchronized void join(long millis) throws InterruptedException { long base = System.currentTimeMillis(); long now = 0; if (millis < 0) { throw new IllegalArgumentException("timeout value is negative"); } if (millis == 0) { while (isAlive()) { wait(0); } } else { while (isAlive()) { long delay = millis - now; if (delay <= 0) { break; } wait(delay); now = System.currentTimeMillis() - base; } } }

 

package chapter3.join;

public class ThreadA extends Thread{
	
	private ThreadB threadB;
	
	public ThreadA(ThreadB threadB) {
		this.threadB = threadB;
	}
	
	@Override
	public void run() {
		super.run();
		try {
			synchronized (threadB) {
				System.out.println("begin A ThreadName="+Thread.currentThread().getName()+"--"+System.currentTimeMillis());
				Thread.sleep(3000);
				System.out.println("end A ThreadName="+Thread.currentThread().getName()+"--"+System.currentTimeMillis());
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}

package chapter3.join;

public class ThreadB extends Thread{
	
	@Override
	synchronized public void run() {
		try {
			super.run();
			System.out.println("begin B ThreadName="+Thread.currentThread().getName()+"--"+System.currentTimeMillis());
			Thread.sleep(3000);
			System.out.println("end B ThreadName="+Thread.currentThread().getName()+"--"+System.currentTimeMillis());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}

package chapter3.join;

public class Test {

	public static void main(String[] args) {
		try {
			ThreadB threadB = new ThreadB();
			ThreadA threadA = new ThreadA(threadB);
			threadA.start();
			threadB.start();
			threadB.join(2000);
			System.out.println("main end:"+System.currentTimeMillis());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

 運行結果1:get

begin A ThreadName=Thread-1--1561019085673
end A ThreadName=Thread-1--1561019088673
main end:1561019088673
begin B ThreadName=Thread-0--1561019088673
end B ThreadName=Thread-0--1561019091673源碼

  • threadB.join(2000)先搶到threadB鎖,而後釋放;
  • ThreadA搶到鎖,打印begin,sleep;
  • 打印end,釋放鎖;
  • threadB.join(2000)和ThreadB爭搶鎖,join再次搶到,發現時間已過,釋放而後打印main end;
  • ThreadB搶到鎖,打印begin,end;

運行結果2:it

begin A ThreadName=Thread-1--1561019572226
end A ThreadName=Thread-1--1561019575226
begin B ThreadName=Thread-0--1561019575226
end B ThreadName=Thread-0--1561019578226
main end:1561019578226

  • threadB.join(2000)先搶到threadB鎖,而後釋放;
  • ThreadA搶到鎖,打印begin,sleep;
  • 打印end,釋放鎖;
  • threadB.join(2000)和ThreadB爭搶鎖,ThreadB搶到,打印begin,sleep,打印end後釋放鎖;
  • mian end最後輸出;
相關文章
相關標籤/搜索