【并发编程】-- 线程的sleep方法、join方法实现原理

96 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第19天,点击查看活动详情

sleep方法

使用sleep方法会使当前正在执行的线程在指定时间内进入睡眠状态,暂时停止执行,但是当前线程不会失去资源的所有权,也就是说使用sleep方法不会释放锁。

方法定义如下:

public static native void sleep(long millis) throws InterruptedException;

​ 使用sleep方法会使当前正在执行的线程在指定的毫秒数加指定的纳秒数的情况下,进入睡眠状态,暂时停止执行,但是当前线程不会失去监视器的所有权,也就是说使用sleep方法不会释放锁。其中,millis表示线程睡眠时间,以毫秒为单位;nacos表示附加的睡眠时间,纳秒为单位,值为0·999999,当millis为负数,nacos的数值范围不为(0,999999)区间内时,会抛出IllegalArgumentException异常,当其他线程中断了当前线程时会抛出InterruptedException异常,若抛出该异常,则当前线程的中断标志位会被清除。

public static void sleep(long millis,int nacos)throws InterruptedException{
	if(millis < 0){
	throw new IllegalArgumentException("timeout value is negative");
	}
	if(nacos < 0 || nacos > 999999){
	throw new IllegalArgumentException("nacos second timeout value out of range");
	}
	if(nacos >= 500000 || (nacos != 0 && millis == 0) ){
	millis++;
	}
	sleep(millis);
}

join方法

​ join方法用于等待线程执行完成,该方法的实现是以isAlive为条件循环调用wait方法的,当线程终止notifyAll时,会被调用,从而唤醒等待线程。millis等待毫秒数,当millis值为负数时,会抛出IllegalArgumentException异常,当其他线程中断了当前线程时,会抛出InterruptedException异常,若抛出该异常,则当前线程中断标志位会被清除。

public final syhchronized 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 deploy = millis - now;
		}
		if(deploy <= 0){
			break;
		}
		wait(deploy);
		now  = System.currentTimeMillis()-base;
	}
}