Java多线程的生命周期与同步锁

Thread state线程生命周期内的几种状态
  • NEW
A thread that has not yet started in this states
  • RUNNABLE
    A thread executing in the Java virtual machine is in this state
  • BLOCKED
    A thread that is blocked waiting for a monitor lock is in this state
  • WAITING
    A thread that is waiting indefinitely for another thread to perform a particular action is in this state.
  • TIMED_WAITING
    A thread that is waiting for another thread to perform an action for up to a specified waiting time is in this state.
  • TERMINATED A thread that has exited in this state.
初始状态(New):新创建了一个线程对象
就绪状态(Runnable):线程对象创建后,调用了该线程的start()方法,处于该状态的线程位于线程池中,处于可运行状态,等待获取CPU资源
运行状态:就绪状态的线程获取了CPU的资源,执行run()方法里面的程序
阻塞状态(Blocked):线程因为某种原因失去的CPU的运行资源。暂时停止运行。直到线程再次进入就绪状态,才会继续开始运行
阻塞状态一共有三种情况:
1.等待阻塞:线程运行时调用wait()方法,JVM使该线程进入等待队列(wait blocked pool),直到notify() / notifyAll(),线程被唤醒进入到锁池(lock blocked pool),准备抢锁回到可运行状态(特别注意:wait()方法会释放同步锁)
2同步阻塞:运行的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入到锁池中
3.其他阻塞:线程在运行时调用join()和sleep()方法,sleep()时间结束,join()终止或IO完成都会回到Runnable状态,等待JVM调度

Thread类的yield方法可以让一个running状态的线程转入runnable

以下情况,持有锁的线程会释放锁
1.执行完同步代码块(synchronized)
2.执行同步代码块的过程中,遇到异常(exception)
3.执行同步代码块的过程中,执行了锁所属对象的wait()方法,这个线程会释放锁,进入等待池
以下情况,同步锁不会被释放
1.执行Thread.sleep()方法,当前线程放弃CPU使用权进入睡眠,睡眠中不会释放锁
2.执行Thread.yield()方法,当前线程放弃CPU使用权,但不会释放锁
3.其他线程执行了当前线程的suspend()方法,当前线程被暂停,但不会释放锁
另外,wait(),notify(),notifyAll()三个方法都是Object类中的方法
锁池:某个线程在进入对象的synchronized方法之前必须先获得该对象的锁,如果该对象的锁正在被其他线程拥有,这个线程就会进入该对象的锁池中。
等待池:wait()方法必须出现在synchronized中,所以在执行wait()之前该线程就已经拥有了该对象的锁,调用wait()方法之后,线程释放对象的锁,进入到该对象的等待池中。直到该对象的notifyAll()方法被调用,那么处于该对象等待池中的线程就会全部进入该对象的锁池中,准备抢锁。如果调用的是该对象的notify()方法,那么仅仅有一个处于该对象的等待池中的线程会随机进入该对象的锁池。

猜你喜欢

转载自blog.csdn.net/kakaluoteyy/article/details/80018451