在启动上述Demo中,理论上最终打印的 i 和 j 的数据是一致的。
错误的中止方式 - stop:如果线程在睡眠期间被stop掉,会导致 i 和 j 打印的数据不一致,我们用synchronized保证原子性的目标是没有达成的,破坏了线程的线程安全。原因:利用stop停止线程,会致使正在运行的程序从中间拦腰折断,导致 i 的自增成功,j 的自增失败。这种中止线程的方式,严重的违反了我们设计线程的用意。正确的线程中止 - Interrupt 如果目标线程在调用Object class的wait()、wait(Long)或者wait(Long,int)方法,join、join(Long、int)或sleep(long,int)方法被阻塞,那么Interrupt会生效,改线程的中端状态将被清除,抛出InterruptedException异常 如果目标线程是被I/O或者NIO中的Channel所阻塞,同样,I/O操作会被中断或者返回特殊异常值。达到中止线程的目的。 如果以上条件都不满足,则会设置此线程的中断状态。 将上述实例中的stop改成Interrupt后,最终输出 i 和 j 的值相同,数据一致。标志位中断线程 如果代码逻辑中是一个循环执行的业务,可以增加一个判断,用来控制线程执行的中止,受限于代码执行的逻辑。如 Demo4: package com.study.basejava.a1_thread_status; public class Demo4 { public volatile static boolean flag = true; public static void main(String[] args) throws InterruptedException { new Thread(()->{ try { while (flag){ // 判断是否运行 System.out.println("运行中"+Thread.currentThread().getState().toString()); Thread.sleep(1000L); } }catch (InterruptedException e){ e.printStackTrace(); } }).start(); // 3秒之后,将状态标志改为False,代表不继续运行 Thread.sleep(3000L); flag = false; System.out.println("程序运行结束"+Thread.currentThread().getState().toString()); } }原文作者: 小呆呆 原文链接 版权声明: 转载请注明出处(必须保留作者署名及链接)
