多线程编程-线程间通信-join方法的使用(六)

方法join的使用

1,主线程启动子线程后,如果主线程项等子线程执行完成后再结束,就要用到join()方法了。

测试代码:

public class JoinThread extends Thread{

	@Override
	public void run() {
		try {
			int value = (int)(Math.random()*10000);
			System.out.println(value);
			Thread.sleep(value);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}	
}
public class RunTest {

	public static void main(String[] args) {
		try {
			JoinThread jt = new JoinThread();
			jt.start();
			jt.join();
			System.out.println("after joinThread finish,print this");
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}
运行结果:

3231
after joinThread finish,print this

方法join的作用是使所属的线程对象t正常执行run()方法中的任务,而使当前线程m进入无限期阻塞,等待t线程运行结束销毁后在继续执行m线程后面的代码。

Join方法具有使线程排队运行的作用,类似同步的运行结果。与synchronized方法的区别:join方法实际是一个synchronized方法,内部使用wait()方法进行等待,而synchronized关键字使用的是“对象监视器”机制做同步。

2,join的过程中,如果当前线程对象被中断,则当前线程出现异常。

测试代码:

public class ThreadA extends Thread{

	@Override
	public void run() {
		for(int i=0; i
public class ThreadB extends Thread{

	@Override
	public void run() {
		try {
			ThreadA ta = new ThreadA();
			ta.start();
			ta.join();
			System.out.println("thread B run end.");
		} catch (InterruptedException e) {
			System.out.println("thread B InterruptedException.");
			e.printStackTrace();
		}
	}	
}
public class ThreadC extends Thread{
	private ThreadB tb;
	
	public ThreadC(ThreadB tb){
		super();
		this.tb = tb;
	}
	@Override
	public void run() {
		tb.interrupt();
	}	
}
public class RunTest {

	public static void main(String[] args) {
		try {
			ThreadB tb = new ThreadB();
			tb.start();
			Thread.sleep(500);
			ThreadC tc = new ThreadC(tb);
			tc.start();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}
运行结果:

thread B InterruptedException.
java.lang.InterruptedException
at java.lang.Object.wait(Native Method)
at java.lang.Thread.join(Unknown Source)
at java.lang.Thread.join(Unknown Source)
at ThreadB.run(ThreadB.java:9)

Join方法和interrupt方法彼此遇到,就会出异常。


3,join(long),可以设定等待的时间。

跟Thread.sleep(long)方法的区别,Thread.sleep(long)方法不会释放锁。

测试代码,验证:Thread.sleep(long)方法不会释放锁。

public class ThreadA extends Thread{
	private ThreadB tb;
	
	public ThreadA(ThreadB tb){
		super();
		this.tb = tb;
	}
	@Override
	public void run() {
		try {
			synchronized(tb){
				tb.start();
				System.out.println("ta run begin time ="+System.currentTimeMillis());
				Thread.sleep(6000);
				System.out.println("ta run end time ="+System.currentTimeMillis());
			}
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}	
}
public class ThreadB extends Thread{

	@Override
	public void run() {
		try {
			System.out.println("tb run begin time ="+System.currentTimeMillis());
			Thread.sleep(5000);
			System.out.println("tb run end time ="+System.currentTimeMillis());
		} catch (InterruptedException e) {
			System.out.println("thread B InterruptedException.");
			e.printStackTrace();
		}
	}	
	
	synchronized public void tbService(){
		System.out.println("print tb service timer="+System.currentTimeMillis());
	}
}
public class ThreadC extends Thread{
	private ThreadB tb;
	
	public ThreadC(ThreadB tb){
		super();
		this.tb = tb;
	}
	@Override
	public void run() {
		tb.tbService();
	}	
}
public class RunTest {

	public static void main(String[] args) {
		try {
			ThreadB tb = new ThreadB();
			ThreadA ta = new ThreadA(tb);
			ta.start();
			Thread.sleep(2000);			
			ThreadC tc = new ThreadC(tb);
			tc.start();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}
运行结果:

ta run begin time =1516180072939
tb run begin time =1516180072939
tb run end time =1516180077940
ta run end time =1516180078940
print tb service timer=1516180078940

可以看到,print tb service timer=1516180078940 这句没有马上输出,而是等到ta的sleep时间到了之后才输出。

因为ta的sleep方法一直持有tb对象的锁,时间是6秒,所以tc只有在6s后,ta释放了tb锁后,才能调用tb的同步方法synchronized public void tbService(){}

修改ThreadA的run方法,把sleep(6000)改成tb.join(),运行结果:

tb run begin time =1516180439457
ta run begin time =1516180439457
print tb service timer=1516180441472
tb run end time =1516180444457
ta run end time =1516180444457

由于join方法释放了锁,tbService方法可以马上执行。

你可能感兴趣的:(join方法,join和sleep的区别,多线程编程)