关于join()与join(long)的区别

1 篇文章 0 订阅
1 篇文章 0 订阅

join()

表示一个线程会无限等待至被等待线程死亡为止。

join(long)

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;
	        }
	    }
}

而使用join(long)表示一个线程最多等待long的时间,如果被等待线程超过这个时间还不死亡就不再等待了。但是,查看源码可以发现,join(long)内部是通过wait()来实现的,而wait()必须获得对象的锁。我们定义一个线程b,还有Main主线程,当在主线程执行b.join(2000)的时候,主线程一定暂停两秒吗?答案是否定的,通过阅读源码可以知道,当主线程执行b.join(2000)的时候是有一个争锁的过程的,如果没有争到锁就必须等待,而这次的等待时间是不算入计数的时间的,所以这就有可能造成主线程等待的时间比规定的时间长。当超过了规定的long时间,join(long)就会开始第二次争锁(从wait()苏醒也必须获得锁)。如果此时还是争不到锁,join(long)就无法通知主线程继续执行后面的代码,主线程继续等待。只有当join(long)争到锁了,向主线程发起通知,主线程才能继续执行。期间等待的过程也可能会超过规定的long时间。综上所诉,join(long)不一样等待时间小于等于long,还有可能大于long。

 

这是一个验证的例子

package test;
class ThreadA extends Thread{
	public void run() {
		synchronized (this) {
			try {
				System.out.println("睡眠5秒");
				Thread.sleep(5000);
				System.out.println("睡完了");
			} catch (InterruptedException e) {
				// TODO 自动生成的 catch 块
				e.printStackTrace();
			}
		}
		try {
			System.out.println("再睡眠5秒");
			Thread.sleep(5000);
			System.out.println("睡完了");
		} catch (InterruptedException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		}
	}
}
public class Main {
	public static void main(String[] args) throws InterruptedException {
		long start = System.currentTimeMillis();
		ThreadA a = new ThreadA();
		a.start();
		a.join(2000);
		long end = System.currentTimeMillis();
		System.out.println("不等了");
		System.out.println("共运行" + (end - start)/1000 + "秒");
	}
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值