java-线程加强-线程的join方法

Join方法

一.概念及作用

join方法四用于在一个线程中,调用其他线程的join方法,则此线程等待其他线程完成任务.

二.特点

1.是Thread类的方法,故只能是线程及其子类调用.
2.底层调用的是object的wait方法.
3.Join()方法会释放锁,但是只能释放它join的对象的锁.

三.代码

功能就是,首先主线程先输出到10;然后等待子线程输出到10;最后主线程再输出剩余的

情况0:主线程或只线程,至少有一方不是同步方法

子线程类

class MyThread extends Thread{
	public Object o;
	public MyThread(Object o) {
		this.o = o;
	}
	
	@Override
	public void run() {
		synchronized (this) {  //子线程加锁
			for(int i = 0; i < 10; i ++) {
				System.out.println("Mythread----" + i);
			}
		}
	}
}

主线程类

public class TestJoin {
	public static void main(String[] args) throws Exception {
		Object o = new Object();
		
		//子线程,加锁对象也是对象o
		MyThread mt = new MyThread(o);
		mt.start();
		
		for(int i = 0 ; i < 20; i ++) {
			System.out.println("main----" + i);
			if(i == 10) {
				mt.join(); //主线程等待对象,即释放锁的对象为mt
			}
		}
	}
}

运行结果:1.主线程和子线程一起,但是当主线程到11的时候必须等待子线程先完成.
在这里插入图片描述

情况一:主线程和子线程,使用不同的锁.

子线程类

class MyThread extends Thread{
	public Object o;
	public MyThread(Object o) {
		this.o = o;
	}
	
	@Override
	public void run() {
		synchronized (o) { //子线程申请o对象锁
			for(int i = 0; i < 10; i ++) {
				System.out.println("Mythread----" + i);
			}
		}
	}
}

主线程

public class TestJoin {
	public static void main(String[] args) throws Exception {
		Object o = new Object();
		
		//子线程,加锁对象也是对象o
		MyThread mt = new MyThread(o);
		mt.start();
		
		synchronized (TestJoin.class) {//主线程加锁对象其他对象
			for(int i = 0 ; i < 20; i ++) {
				System.out.println("main----" + i);
				if(i == 10) {
					mt.join(); //主线程等待对象,即释放锁的对象为mt
				}
			}
		}
	}
}

运行结果:结果是主子线程各自运行各自的.
在这里插入图片描述

情况2:主线程和子线程,使用相同的锁,但是锁住的这个对象不是join对象

子线程类

class MyThread extends Thread{
	public Object o;
	public MyThread(Object o) {
		this.o = o;
	}
	
	@Override
	public void run() {
		synchronized (o) {  //锁住的是对象o
			for(int i = 0; i < 10; i ++) {
				System.out.println("Mythread----" + i);
			}
		}
	}
}

主线程类

public class TestJoin {
	public static void main(String[] args) throws Exception {
		Object o = new Object();
		
		//子线程,加锁对象也是对象o
		MyThread mt = new MyThread(o);
		mt.start();
		
		synchronized (o) {//主线程加锁对象也是对象o
			for(int i = 0 ; i < 20; i ++) {
				System.out.println("main----" + i);
				if(i == 10) {
					mt.join(); //主线程等待对象,即释放锁的对象为mt
				}
			}
		}
	}
}

运行结果:主线程进入等待死循环,且没有释放o对象锁.
在这里插入图片描述

情况3:主线程和子线程,使用相同的锁,锁住的就是join的子线程对象

子线程类

class MyThread extends Thread{
	public Object o;
	public MyThread(Object o) {
		this.o = o;
	}
	
	@Override
	public void run() {
		synchronized (this) { //锁住的就是本对象
			for(int i = 0; i < 10; i ++) {
				System.out.println("Mythread----" + i);
			}
		}
	}
}

主线程类

public class TestJoin {
	public static void main(String[] args) throws Exception {
		Object o = new Object();
		
		//子线程,加锁对象也是对象o
		MyThread mt = new MyThread(o);
		mt.start();
		
		synchronized (mt) {//主线程加锁对象就是join的线程对象
			for(int i = 0 ; i < 20; i ++) {
				System.out.println("main----" + i);
				if(i == 10) {
					mt.join(); //主线程等待对象,即释放锁的对象为mt
				}
			}
		}
	}
}

运行结果:主线程(0-10)>子线程(0-9)>主线程
在这里插入图片描述

四.使用场景总结

使用场景:

join一般应用于两个线程之间的执行顺序,不擅长于控制多个程序之间的排序控制,常用于主线程等待子线程返回结果.如果期望多个线程之间的排序,可参考CountDownLaunch等.

使用注意事项:

1.一定是main线程中调用等待的线程的join()方法
2.如果主线程和子线程都是同步方法,则需要子线程加锁对象为this,主线程加锁对象为join的线程…这样才能释放锁.
3.join()方法会释放锁,但是只会释放join的线程对象的锁.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值