线程的五种状态
新建
新创建一个线程对象,但是没有调用此对象的启动方法。就绪
线程创建后,调用了start()的方法。该线程位于运行的线程池中,等待cpu调度。
运行
线程获取了cpu时间片,执行程序代码。
阻塞
线程因为某种原因放弃了对CPU的使用,暂时停止运行。
等待阻塞:运行的线程执行了wait()方法,jvm把该线程放入到等待池中。
同步阻塞:运行的线程获取同步锁的时候,若该同步锁被其余的线程占用,则jvm会把线程放入到锁池中
其他阻塞:运行的线程执行sleep或者join方法,或者I/O请求,jvm会把该线程设置为阻塞状态。
死亡
线程正常结束进入死亡状态。

join
等待这个线程结束,也就是说t.join()方法阻塞调用此方法的线程进入等待阻塞状态,直到t完成,此线程在继续。
我门看一下join的源代码,也就是说当mills等于0的时候,会进入到while(isAlive())的循环,即只要子线程或者,主线程就不停等待。虽然调用的是子线程的wait()方法,但是他是通过主线程去调用的,所以休眠的是主线程。
1 | public final void join() throws InterruptedException { |
wait
暂停当前线程进入等待状态。
我门看下面这段代码
1 | public class ThreadTest implements Runnable { |
运行结果:
1.如果secondMethod()中调用的是sleep(2000)
310
number=310
2.如果secondMethod()中调用的是this.wait(2000)
110
number=310
分析:main方法的优先等级高于子线程的优先等级,所以会先调用secondMethod(),如果secondMethod()中是sleep 那么ThreadTest处于休眠状态,这时候ThreadTest线程启动调用run方法,但是这时候secondMethod()已经拿到ThreadTest的锁,并且sleep不会释放锁,那么这时候firstMethod()方法进不来,需要等待sleep结束后,这时候number会加上这个200,然后在firstMethod()中在加100,结果为310,main方法中也为310.
如果secondMethod()中是wait(),wait()方法会释放锁,这时候wait()暂停当前调用他的main线程,因为锁被释放所以firstMethod()方法直接执行,输出为110,wait结束后,main线程输出最终结果310.
sleep join wait 方法的区别
Sleep()暂停当前线程,不会释放锁。
Join() 和wait() 暂停调它用的线程,会释放锁。
join() 是object中的方法,wait()是thread中的方法。
wait()方法必须在synchronized中,否则会抛出java.lang.IllegalMonitorStateException
join() 方法可以不在synchronized中。
yield()
Yield()的作用是让步,它能够让当前线程从运行状态到就绪状态,其他线程可以获取到执行的权,也有可能是当前线程又从就绪状态到运行状态。
举个例子:一群朋友在排队上车,这时候到yield 上车的时候,他不马上上去,而是说大家一起上,谁先上去就是谁的。那么有可能是yiel的又上去了,也有可能是其余人(线程)上去了,到了运行状态。