并发编程理论基础——Java线程的生命周期(下)(九)

 

RUNNABLE 与 WAITING 的状态转换(3种)

  1. 获得 synchronized 隐式锁的线程,调用无参数的 Object.wait() 方法。
  2. 调用无参数的 Thread.join() 方法。
    • 其中的 join() 是一种线程同步方法,例如有一个线程对象 thread A,当调用 A.join() 的时候,执行这条语句的线程会等待 thread A 执行完,而等待中的这个线程,其状态会从 RUNNABLE 转换到 WAITING。当线程 thread A 执行完,原来等待它的线程又会从 WAITING 状态转换到 RUNNABLE。
  3. 调用 LockSupport.park() 方法。
    • LockSupport对象,Java并发包中的锁都是基于它实现的
    • 调用 LockSupport.park() 方法,当前线程会阻塞,线程的状态会从 RUNNABLE 转换到 WAITING。
    • 调用 LockSupport.unpark(Thread thread) 可唤醒目标线程,目标线程的状态又会从 WAITING 状态转换到 RUNNABLE。

RUNNABLE 与 TIMED_WAITING 的状态转换(五种)

  1. 调用带超时参数的 Thread.sleep(long millis) 方法;
  2. 获得 synchronized 隐式锁的线程,调用带超时参数的 Object.wait(long timeout) 方法;
  3. 调用带超时参数的 Thread.join(long millis) 方法;
  4. 调用带超时参数的 LockSupport.parkNanos(Object blocker, long deadline) 方法(为线程调度目的禁用当前线程,直到指定的等待时间,除非许可可用);
  5. 调用带超时参数的 LockSupport.parkUntil(long deadline) 方法(为线程调度目的禁用当前线程,直到指定的最后期限,除非许可可用)。

从 NEW 到 RUNNABLE 状态

  1. Java 刚创建出来的 Thread 对象就是 NEW 状态,而创建 Thread 对象主要有两种方法。一种是继承 Thread 对象,重写 run() 方法。
  2. 另一种是实现 Runnable 接口,重写 run() 方法,并将该实现类作为创建 Thread 对象的参数。
  3. NEW 状态的线程,不会被操作系统调度,因此不会执行。Java 线程要执行,就必须转换到 RUNNABLE 状态。从 NEW 状态转换到 RUNNABLE 状态很简单,只要调用线程对象的 start() 方法就可以了。

从 RUNNABLE 到 TERMINATED 状态

  1. 线程执行完 run() 方法后,会自动转换到 TERMINATED 状态,当然如果执行 run() 方法的时候异常抛出,也会导致线程终止。
  2. 有时候我们需要强制中断 run() 方法的执行,例如 run() 方法访问一个很慢的网络,我们等不下去了,想终止怎么办呢?
  3. Java 的 Thread 类里面倒是有个 stop() 方法,不过已经标记为 @Deprecated,所以不建议使用了。正确的姿势其实是调用 interrupt() 方法。

那 stop() 和 interrupt() 方法的主要区别是什么呢?

  1. stop() 方法会真的杀死线程,如果线程持有 ReentrantLock 锁,被 stop() 的线程并不会自动调用 ReentrantLock 的 unlock() 去释放锁,那其他线程就再也没机会获得 ReentrantLock 锁。
    • 手动加锁解锁的,加了锁后执行stop中断后,就不能解锁了,永远阻塞了;
    • 而synchronized的加锁解锁是编译器操作的,stop后编译器会自动解锁
  2. interrupt() 方法仅仅是通知线程,线程有机会执行一些后续操作,同时也可以无视这个通知。
  3. 被 interrupt 的线程,是怎么收到通知的呢?一种是异常,另一种是主动检测。
  4. 当线程 A 处于 WAITING、TIMED_WAITING 状态时,如果其他线程调用线程 A 的 interrupt() 方法,会使线程 A 返回到 RUNNABLE 状态,同时线程 A 的代码会触发 InterruptedException 异常
  5. 转换到 WAITING、TIMED_WAITING 状态的触发条件,都是调用了类似 wait()、join()、sleep() 这样的方法,这些方法的签名,都会存在 throws InterruptedException 这个异常。这个异常的触发条件就是:其他线程调用了该线程的 interrupt() 方法
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值