LockSupport.park(): 暂停线程
LockSupport.unpark():唤醒线程 先unpark再park(),会唤醒后来park的线程。
wait()/notify 与 park()/unpark:
1.wait/notify必须与Object Monitor(拿到锁)联合使用。park/unpark不用。
2.notify是随机唤醒某个线程,notifyAll是唤醒所有线程。unpark()可以唤醒指定线程。
3.必须先使用wait在使用notify;park/unpark不在意先后使用顺序。
park/unpark执行原理:
每个Thread都有一个Parker对象,Parker里有_counter(0.1两个值), _cond 和_mutex;
park(_counter=0)
先park(Thread在_Cond中)再unpark(_counter=1)的unpark过程
先执行Unpark再执行park:
线程状态转换:
初始状态(New):创建了Java的线程对象,没有与操作系统底层线程联系起来。
1.New-->Runnable
New-->Runnable:Thread对象调用start方法后与操作系统底层线程关联起来,交给cpu调度执行。Runnable(可运行状态):等待cpu分配时间片;Runnable(运行状态):正在执行;Runnable(阻塞状态):为了获取IO等其他资源在阻塞队列里。
2.Runnable-->Waiting
Runnable-->Waiting: 获得锁的Thread调用wait()方法进入到Monitor的waitSet里面;
Waiting-->Runnable:获得锁的Thread调用notify()/notifyAll()/intterupt()方法成功唤醒线程。
Waiting-->Blocked:获得锁的Thread调用notify()/notifyAll()/intterupt()方法没有唤醒线程。
Runnable-->Blocked: Thread获得cpu时间片后再去获得锁失败后,进入Monitor的EntryList Blocked队列里。
3.Runnable-->Waiting
Runnable-->Waiting: Thread1里调用t2.join(),使Thread1从Runnable变成waiting。
Waiting-->Runnable: Thread1里调用t2.join(),再用Thread1调用interrupt. Thread1从waiting变Runnable。
4.Runnable-->Waiting
Runnable-->Waiting: Thread1里调用LockSupport.park(),使Thread1从Runnable变成waiting。
Waiting-->Runnable: Thread1里调用LockSupport.unpark()/interrupt,使Thread1从Waiting变成Runnable.
5.Runnable-->Timed_Waiting
Runnable-->Timed_Waiting: 线程获得锁后调用了wait(long timeout).
线程达到执行时间,线程调用了notify/notifyAll/interrupt后,线程竞争锁
竞争成功:Timed_waiting-->Runnable
竞争失败:Timed_Waiting-->Blocked
6.Runnable-->Timed_Waiting
Runnable-->Timed_Waiting: 当前线程调用了t.join(long timeout).
线程达到时间/当前线程调用了interrupt,当前线程从Timed_waiting-->Runnable
7.Runnable-->Timed_Waiting
Runnable-->Timed_Waiting: 当前线程调用了Thread.sleep(long timeout).
等待超时后,当前线程从Timed_Waiting-->Runnable。
8.Runnable-->Timed_Waiting
Runnable-->Timed_Waiting: 当前线程调用了LockSupport.parkNanos(long nanos)/ LockSupport.parkUtil(long millis)
线程调用LockSupport.unpark(目标线程)/interrupt()/等待超时,会让目标线程从Timed_Waiting-->Runnable。
9.Runnable-->Blocked
Runnable-->Blocked:t线程用synchronized(obj)获取obj锁时,如果已有线程持有obj锁,那么t线程就会进入Blocked List里.
如果已获得锁的线程执行完毕,就会唤醒Block List里面的所有线程,如果t线程竞争成功获得锁,那么就会从Blocked-->Runnable.若竞争失败,则仍是Blocked状态。
10.Runnable-->Terminated
Runnable-->Terminated:当前线程全部执行完毕。