最近有点忙,又有其他的事情,所以一直没有开始写这篇,感觉很惭愧。
上一章讲了太多的东西,其实每一个小细节都可以写成一长篇,这一章会尽量用精简的方式把坑填上。
Java的线程状态
想要学好并发,还是得知道线程的生命周期,先看一下线程的生命周期:
在线程的运行周期中会有状态与锁有关,所以先要讲解线程的状态,才能继续讲锁。
sleep
sleep会让当前线程进入”睡眠”状态,把执行的机会让给其他线程。
类似于迅雷下载,当前正在下载N部片子,可同时执行任务数为M(M<N),暂停当前任务后,正在等待的任务才有机会提前运行,否则只有当前任务结束后,才会开始。
但是,sleep不会释放锁,如果有同步块、锁之类的,sleep后,别的线程仍然不能访问已经被锁住的数据。
wait、notify、notifyAll
在使用wait和notify的时候需要用synchronized锁住对象,以此来保证线程安全。
使用wait后,会暂时地将锁释放,使当前线程处于等待状态,从而使别的线程可以访问到资源,唤醒(notify)或者使用了wait(long)线程苏醒后就会重新占用锁,如果使用了interrupte去中断wait,就会抛出InterruptedException。
需要注意的是,wait、notify、notifyAll,都是属于Object类中的方法,而不是属于Thread,这意味着使用对象的方法,会影响到访问此对象的线程的状态,所以前面提到需要用synchronized保证线程。
yield
Causes the calling Thread to yield execution time to another Thread that
is ready to run. The actual scheduling is implementation-dependent.
这是官方的注释,调用Thread.yield()方法,只是让线程进入准备运行状态,把CPU资源让给别的线程提前运行。
join
Thread.join()
看字面意思像是合并,其实从效果上来看更像”插队”,b.join,那么a必须等b执行完才能继续往下执行。
Java中的锁
Java中经常用到的锁有:
- synchronized
- Lock