
wait方法和notify方法都是Object类的方法
object.wait():让当前获取锁的线程进入waiting状态,并进入waitlist队列object.wait(long n):让当前获取锁的线程进入waiting状态,并进入waitlist队列,等待n秒后自动唤醒object.notify():在waitlist队列中挑一个线程唤醒object.notifyAll():唤醒所有在waitlist队列中的线程它们都是之间协作的手段,只有拥有对象锁的线程才能调用这些方法,否则会出现IllegalMonitorStateException异常
wait调用条件:owner线程获取了该对象的锁,但是发现自己条件不满足使用共享资源的条件/竞态条件存在时,会调用wait方法进入waiting状态并进入Monitor对象的waitlist中,释放对象锁
处于waiting状态中的线程可以被notify/notifyAll方法唤醒,唤醒之后不一定马上可以获取锁,仍需进入EntryList竞争锁
join是使用了保护性暂停模式,并在此基础上扩展了超时等待
public final synchronized void join(long millis)throws InterruptedException {
//开始时间
long base = System.currentTimeMillis();
//经历时间
long now = 0;
if (millis < 0) {
//如果指定等待时间等于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) {
//等待时间小于0直接退出循环
break;
}
//等待这一轮应该等待的时间,防止唤醒后的条件不满足再次等待原有时间导致超时
wait(delay);
//求出经历的时间
now = System.currentTimeMillis() - base;
}
}
}park方法和unpark方法是LockSupport类中的方法
LockSupport.park():用于暂停当前的线程LockSupport.unpark(thread):用于恢复某个线程,既可以在park()之前调用也可以在之后调用wait-notify是Object类的方法,必须结合加锁对象使用,park-unpark没有限制notify随机唤醒一个线程,notifyAll唤醒全部线程,park(thread)唤醒指定的线程notify必须用在wait之后,unpark既可以用在park之前,也可以用在park之后每个线程都会关联一个Parker(jvm层面)对象,有一个当前线程许可计数permit
LockSupport.park():调用park时,会先检查permit,如果大于0则将permit-1后返回,线程继续执行.如果小于0则线程进入阻塞状态,等待被唤醒或打断LockSupport.unpark(thread):调用unpark时,将permit+1,
以下是线程各个状态之间的转换以及调用的方法
NEW-->RUNNABLE
thread.start():thread线程的状态NEW-->RUNNABLERUNNABLE<-->WAITING
synchronized(obj)代码块,获取对象锁之后obj.wait():当前线程的状态RUNNABLE-->WAITINGobj.notify() 或 obj.notifyAll() 或 obj.interrupt():WAITING-->RUNNABLEWAITING-->BLOCKEDthread.join():当前线程中调用线程thread的join方法会在thread线程对象上的监视器等待,当前线程的状态RUNNABLE-->WAITINGthread线程运行结束 或 被打断:当前线程的状态WAITING-->RUNNABLELockSupport.park(): 当前线程的状态RUNNABLE-->WAITINGLockSupport.unpark(thread):指定线程的状态WAITING-->RUNNABLERUNNABLE<-->TIMED_WAITING
synchronized(obj)代码块,获取对象锁之后obj.wait(long n):当前线程的状态RUNNABLE-->TIMED_WAITING当前线程等待n秒 或 被唤醒和打断:TIMED_WAITING-->RUNNABLETIMED_WAITING-->BLOCKEDThread.sleep(long n):当前线程的状态RUNNABLE-->TIMED_WAITING当前线程等待n秒:竞争锁成功,当前线程的状态TIMED_WAITING-->RUNNABLELockSupport.parkNanos(long nanos) 或 LockSupport.parkUnitl(long millis):当前线程状态:RUNNABLE-->TIMED_WAITINGLockSupport.unpark(thread) 或 被打断 或 等待超时:目标线程状态TIMED_WAITING-->RUNNABLERUNNABLE<-->BLOCKED
RUNNABLE-->BLOCKEDBLOCKED-->RUNNABLEBLOCKEDRUNNABLE<-->TERMINATED
RUNNABLE-->TERMINATED