gpt4 book ai didi

Java线程/ volatile

转载 作者:搜寻专家 更新时间:2023-10-31 08:12:42 25 4
gpt4 key购买 nike

我有一个主题:

class Foo extends Thread
{
boolean active = true;

public void run()
{
while(active)
{
//do stuff
}
}

public void end()
{
active = false;
}

public void hibernate()
{
synchronized(this)
{
wait();
}
}
}

如果另一个线程调用 end()Foo 会立即看到 active 现在是 false 吗?具体来说,因为 active 不是 volatile,所以我不确定它是否会。我最初创建 end() 作为避免 volatile 的巧妙方法,但现在我不确定它是否真的会按照我的意图进行。此外,如果另一个线程调用 hibernate(),哪个线程会进入休眠状态?我打算 Foo sleep ,所以如果这不符合我的意图,欢迎提出替代建议。

最佳答案

If another thread calls end(), will Foo immediately see that active is now false?

不,不会的。或者至少,它不会一直看到它。

如果您希望 run 始终立即看到新值,则在分配给变量的线程和读取变量的线程之间必须存在“在其后”的关系。这可以实现:

  • 通过声明 active volatile,
  • 通过在读写变量的语句周围放置synchronized block ,
  • 通过使变量成为“原子”类型;例如AtomicBoolean,或者
  • 通过使用其他一些合适的并发类;查看 java.util.concurrent.* 包。

... a clever way of avoiding volatile ...

将变量声明为 volatile 是确保正确同步的一种方法。事实上,适当的同步会增加性能开销。然而,适当的同步对于您的应用程序可靠地工作是必不可少的,避免它并不是“聪明”的做法。

(如果没有适当的同步,您的程序可能大部分时间仍然可以工作,甚至可能总是在某些机器上工作。但是,偶尔它不会工作,实际行为可能取决于您使用的机器运行程序,机器负载是多少,以及其他事情。)

Additionally, if another thread calls hibernate(), which thread will go to sleep?

进行调用的线程将进入 hibernate 状态。除非其他线程对同一个 Foo 对象执行 notifynotifyAll,否则它不会醒来。

如果您只是想让应用程序进入 hibernate 状态并稍后唤醒,请使用 Thread.sleep。但请注意,以错误的方式使用 sleep 会使您的应用程序变慢且无响应。

关于Java线程/ volatile ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7212155/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com