这些方法也可以让线程退出

16 篇文章 0 订阅
1 篇文章 0 订阅
public class MyselfTest {

    public static boolean flag = false;

    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(() ->{
            int i = 0;
            while (!flag) {
                i++;
            }
            System.out.println("i = " + i);
        });
        thread.start();
        Thread.sleep(1000);
        flag = true;
    }
}

该代码按照逻辑来说,flag变为true之后是会打印出结果的,但代码并未退出且打印出结果,这是一个可见性问题。那有哪些方法可以让线程退出呢?

  • print就可以导致循环结束
    int i = 0;
    while (!flag) {
        i++;
        System.out.println("i = " + i);
    }

这里有三个解释:

  1. println底层用了synchronized这个同步关键字,这个同步会防止循环期间对于stop值的缓存
  2. 因为println有加锁操作,而释放锁的操作,会强制的把工作内存中涉及到的写操作同步到主内存,可以通过如下代码去证明:
while (!flag) {
        i++;
        synchronized (MyselfTest.class) {
            
        }
    }

上述代码只是加锁了并未做任何操作也能达到同样的效果
3. 从IO角度来说,println本质上就是IO操作,我们知道IO的效率一定要比CPU的计算效率慢的多,所以IO可以使得CPU有时间去做内存刷新的事情,从而导致这个现象。比如在里面定义一个new File("")同样会达到效果

  • Thread.sleep(0)
while (!flag) {
        i++;
        try {
            Thread.sleep(0);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

Thread.sleep(0)会导致线程切换,从而导致缓存失效获取到最新的数值

  • volatile关键字(保持可见性)
  1. 修改volatile变量时会强制将修改后的值刷新的主内存中。
  2. 修改volatile变量后会导致其他线程工作内存中对应的变量值失效。因此,再读取该变量值的时候就需要重新从读取主内存中的值。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值