我有一个具有“卡片”对象的课程。该类不断检查对象是否不再为null。只有一个其他线程可以更新此对象。我应该像下面的代码那样做吗?使用volatile?Syncronized?锁(我不知道如何使用真的)?您认为最简单的解决方案是什么?
Class A{
public Card myCard = null;
public void keepCheck(){
while(myCard == null){
Thread.sleep(100)
}
//value updated
callAnotherMethod();
}
另一个主题有以下内容:
public void run(){
a.myCard = new Card(5);
}
你有什么建议?
答案 0 :(得分:0)
如果您打算对其进行轮询,则从另一个线程进行修改时,该变量需要是易变的,但更好的解决方案是使用wait()
/ notify()
甚至Semaphore
来保持你的另一个线程处于睡眠状态,直到初始化myCard
变量。
答案 1 :(得分:0)
看起来你有一个经典的制作人/消费者案例。
您可以使用wait()/ notify()方法处理此情况。请参阅此处以获取示例:How to use wait and notify in Java?
或者在这里,更多示例:http://www.programcreek.com/2009/02/notify-and-wait-example/
答案 2 :(得分:0)
您应该使用正确的等待事件(请参阅Guarded Block教程),否则您可能会遇到“观察”线程在看到Card
的完全初始化成员字段之前看到该引用的风险。同样wait()
将允许线程休眠而不是在紧密的while循环中吸收CPU。
例如:
Class A {
private final Object cardMonitor = new Object();
private volatile Card myCard;
public void keepCheck () {
synchronized (cardMonitor) {
while (myCard == null) {
try {
cardMonitor.wait();
} catch (InterruptedException x) {
// either abort or ignore, your choice
}
}
}
callAnotherMethod();
}
public void run () {
synchronized (cardMonitor) {
myCard = new Card(5);
cardMonitor.notifyAll();
}
}
}
我在上面的示例中将myCard
设为私有。我确实建议在这种情况下避免使用大量的公共字段,因为代码最终会变得很乱。
另请注意,您不需要 cardMonitor
- 您可以使用A
本身,但拥有单独的监视器对象可以让您更好地控制同步。 / p>
请注意,通过上述实现,如果在run()
执行期间调用callAnotherMethod()
,则会更改myCard
,这可能会中断callAnotherMethod()
(您未显示) 。在同步块中移动callAnotherMethod()
是一种可能的解决方案,但您必须根据您的要求确定适当的策略。