我有一个线程:
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()
, will Foo
立即看到active
is now false
?具体来说,因为active
isn't volatile
,我不确定它会。我最初创建的end()
作为避免不稳定的聪明方法,但现在我不确定它是否真的会达到我的预期。
另外,如果另一个线程调用hibernate()
,哪个线程将进入睡眠状态?我打算Foo
睡觉,所以如果这不能达到我的目的,那么非常欢迎其他建议。
如果另一个线程调用 end(),Foo 会立即看到 active 现在为 false 吗?
不,不会。或者至少,它不会一直看到它。
如果你想run
为了始终立即看到新值,分配给变量的线程和读取变量的线程之间必须存在“随后出现”的关系。这可以实现:
- 通过声明
active
易挥发的,
- 通过把
synchronized
围绕读取和写入变量的语句进行块,
- 通过使变量成为“原子”类型;例如
AtomicBoolean
, or
- 通过使用其他一些适当的并发类;看到
java.util.concurrent.*
包。
...避免波动的巧妙方法...
将变量声明为易失性是确保正确同步的一种方法。事实上,正确的同步会带来性能开销。然而,正确的同步对于应用程序的可靠工作至关重要,避免它并不“聪明”。
(如果没有适当的同步,您的程序可能在大多数时间仍然可以工作,甚至可能总是在某些机器上工作。但是,有时它不会工作,实际行为可能取决于您运行该程序的机器,机器负载是什么,以及其他事情。)
另外,如果另一个线程调用 hibernate(),哪个线程会进入睡眠状态?
发出调用的线程将进入睡眠状态。除非其他线程执行以下操作,否则它不会醒来notify
or notifyAll
在同一个 Foo 对象上。
如果您只是想让应用程序进入睡眠状态并稍后唤醒,请使用Thread.sleep
。但要注意使用sleep
错误的方式可能会使您的应用程序变得缓慢且无响应。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)