zy_yuanwei 2024-09-23 14:58 采纳率: 0%
浏览 7

Java并发编程可见性问题

static int x;
public static void main(String[] args) {
Thread t2 = new Thread(()->{
while(true) {
if(Thread.currentThread().isInterrupted()) {
System.out.println(x);
break;
}
}
},“t2”);
t2.start();
new Thread(()->{
try {
sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
x = 10;
t2.interrupt();
},“t1”).start();
while(!t2.isInterrupted()) {
Thread.yield();
}
System.out.println(x);
}

Java代码,为什么在t2线程被打断后,主线程的循环不会结束,当我在主线程中加入System.out.println("")或者去除Thread.yield()之后 循环可以正常结束,给我的感觉是Thread.yield影响了t2线程打断状态的可见性,等个解答谢谢

  • 写回答

1条回答 默认 最新

  • 一轮明月照丘壑 2024-09-23 20:07
    关注

    以下回复参考:皆我百晓生券券喵儿等免费微信小程序作答:

    这个问题涉及到Java并发编程中的可见性问题,主要和Java内存模型中的线程间通信和可见性有关。在你提供的代码中,确实存在可见性问题,导致主线程无法正确检测到t2线程的中断状态。下面我会详细解释这个问题,并给出解决方案。

    问题分析:

    1. 可见性问题:当一个线程修改了共享变量的值,另一个线程要能够看到这个修改的值,必须满足一定的条件。在Java中,如果变量是volatile的,或者通过synchronized块进行同步,就能保证可见性。在你提供的代码中,变量x虽然是静态的,但没有使用volatile关键字或synchronized块,因此不能保证可见性。
    2. Thread.yield()的影响Thread.yield()方法会使当前线程让出CPU资源,让其他线程有机会运行。但由于可见性问题没有解决,即使主线程调用了t2.interrupt(),t2线程的打断状态可能没有被主线程立即感知到。因此,主线程循环不会结束。
    3. 加入System.out.println("")的影响:在主线程中加入System.out.println("")可能会导致CPU资源被频繁切换给主线程,这样主线程更有可能感知到t2线程的中断状态。但这并不是一个可靠的解决方案,因为这种行为依赖于JVM和操作系统的调度行为,无法保证在所有情况下都能正常工作。

    解决方案:

    1. 使用volatile关键字:将变量x声明为volatile,以确保其可见性和禁止指令重排序优化。这样主线程就能正确感知到t2线程中断后x的值的变化。
    static volatile int x;
    
    1. 使用synchronized块:在修改和读取x的地方使用synchronized块来保证线程安全。这也是一种有效的解决方案。
    2. 检查中断原因:在t2线程的循环中,除了检查中断状态外,还可以检查中断的原因。使用Thread.currentThread().isInterrupted()方法检查中断状态的同时,可以通过Thread.currentThread().getInterruptCause()获取中断的原因。这样即使存在可见性问题,也可以更清晰地了解为何线程被中断。

    总之,要解决可见性问题,需要确保共享变量的修改对其它线程是可见的。在Java中,可以通过使用volatile关键字或synchronized块来实现这一点。

    评论

报告相同问题?

问题事件

  • 创建了问题 9月23日

悬赏问题

  • ¥15 惠普360g9的最新bios
  • ¥15 配置hadoop时start-all.sh老是启动失败
  • ¥30 这个功能用什么软件发合适?
  • ¥60 微信小程序,取消订单,偶尔订单没有改变状态
  • ¥15 用pytorch实现PPO算法
  • ¥15 关于调制信号的星座图?
  • ¥30 前端传参时,后端接收不到参数
  • ¥15 这是有什么问题吗,我检查许可证了但是显示有呢
  • ¥15 机器学习预测遇到的目标函数问题
  • ¥15 Fluent,液体进入旋转区域体积分数不连续