Java多线程升级篇(四)——join方法

这一篇的内容是关于线程中的方法join的使用。在使用线程的过程中,一个线程等待另外的一个线程的结果是很常见的需求。这样主线程创建一个从线程并且需要从线程的结果,这个时候就可以使用join方法,将主线程自动挂起并释放锁,从线程执行完毕以后再唤醒主线程继续的执行。
下面就简单讲讲join方法的使用场景以及和sleep方法的比较。

Join方法

代码如下所示:

public class New_thread extends Thread{
	public void run() {
		try {
			int a=(int) (Math.random()*10000);
			System.out.println(a);
			Thread.sleep(a);
		}catch(InterruptedException e) {
			e.printStackTrace();
		}
	}
}
public class Test_thread{
	public static void main(String[] args){
		try {
			New_thread test=new New_thread();
			test.start();
			test.join();
			System.out.println("等待test执行完毕");
		}catch(InterruptedException e) {
			e.printStackTrace();
		}
	}
}

运行结果:

java集合用多线程处理 java多线程 join_System


Join方法的作用是让线程对象的x正常执行run方法中的任务,而使当前线程中线程z无限期的阻塞,等待线程x销毁后再继续的执行线程z后面的代码。

Join具有让线程排队运行的作用,有些类似于同步的运行效果。有点类似于synchronized关键字,但是Join在内部使用的是wait方法进行等待,而synchronized关键字使用的是“对象监视器”原理作为同步。

Join方法和异常

Join方法如果当前线程对象被中断,线程会出现异常。

public class New_thread extends Thread{
	public void run() {
		try {
		for(int i=0;i<Integer.MAX_VALUE;i++) {
			System.out.println(i);
			Thread.sleep(1000);
			String newString=new String();
			Math.random();
		}
		}catch(InterruptedException e) {
			e.printStackTrace();
		}
	}
}
public class Another_thread extends Thread{
	public void run() {
		try {
			New_thread t=new New_thread();
			t.start();
			t.join();
			System.out.println("Anothre_thread run over!");
		}catch(InterruptedException e) {
			System.out.println("Anothre_thread catch Exception!");
			e.printStackTrace();
		}
	}
}
public class Test_thread{
	public static void main(String[] args){
		try {
			Another_thread t=new Another_thread();
			t.start();
			t.interrupt();
			Thread.sleep(500);
			System.out.println("等待test执行完毕");
		}catch(InterruptedException e) {
			e.printStackTrace();
		}
	}
}

运行结果:

java集合用多线程处理 java多线程 join_java集合用多线程处理_02


运行的时候会发现Another_thread会发生异常,但是New_thread线程还在继续执行,每一秒打印一个数字,是正常执行状态。

Join方法和sleep方法比较

两个方法都是等待,但是join方法内部使用的是wait方法进行实现,所以有一个好处就是等待的时候,是释放锁的,如下代码所示:

public class New_thread extends Thread{
	public void run() {
		try {
			System.out.println("New_thread "+System.currentTimeMillis());
			Thread.sleep(5000);
			System.out.println("New_thread end "+System.currentTimeMillis());
		}catch(InterruptedException e) {
			e.printStackTrace();
		}
	}
	synchronized public void Service() {
		System.out.println("打印了Service!");
	}
}
public class Another_thread extends Thread{
	private New_thread test;
	public Another_thread(New_thread t) {
		this.test=t;
	}
	public void run() {
		try {
			synchronized(this.test) {
				test.start();
				Thread.sleep(10000);
				System.out.println("Anothre_thread run over!");
			}
		}catch(InterruptedException e) {
			System.out.println("Anothre_thread catch Exception!");
			e.printStackTrace();
		}
	}
}
public class Test_thread{
	public static void main(String[] args){
		try {
			New_thread test=new New_thread();
			Another_thread at=new Another_thread(test);
			at.start();
			Thread.sleep(1000);
			test.Service();
			System.out.println("end!"+System.currentTimeMillis());
		}catch(InterruptedException e) {
			e.printStackTrace();
		}
	}
}

运行结果:

java集合用多线程处理 java多线程 join_java_03


所以可见sleep方法运行的时候,是不释放锁的,这样的情况下,另外的线程想要对象的执行方法,就必须要等待对象的锁释放才能进行。

但是join是没有这个问题的,join的时候是释放锁的,这样另外的线程就能使用对象的方法了。

public class New_thread extends Thread{
	public void run() {
		try {
			System.out.println("New_thread "+System.currentTimeMillis());
			Thread.sleep(5000);
			System.out.println("New_thread end "+System.currentTimeMillis());
		}catch(InterruptedException e) {
			e.printStackTrace();
		}
	}
	synchronized public void Service() {
		System.out.println("打印了Service!");
	}
}
public class Another_thread extends Thread{
	private New_thread test;
	public Another_thread(New_thread t) {
		this.test=t;
	}
	public void run() {
		try {
			synchronized(this.test) {
				test.start();
				test.join(10000);
				System.out.println("Anothre_thread run over!");
			}
		}catch(InterruptedException e) {
			System.out.println("Anothre_thread catch Exception!");
			e.printStackTrace();
		}
	}
}
public class Test_thread{
	public static void main(String[] args){
		try {
			New_thread test=new New_thread();
			Another_thread at=new Another_thread(test);
			at.start();
			Thread.sleep(1000);
			test.Service();
			System.out.println("end!"+System.currentTimeMillis());
		}catch(InterruptedException e) {
			e.printStackTrace();
		}
	}
}

运行结果:

java集合用多线程处理 java多线程 join_java_04


在线程Another_thread正在等待结果的时候锁是释放的,这样main函数的线程是可以调用其中的方法的。

所以join方法有释放锁的特点,这样的情况下,别的线程是可以调用对象的方法的。

Join方法的特性比较简单,这一篇的内容也比较简单。总体上来说不是太难,这一次就偷偷懒,简单说说,嘿嘿。