我是否需要在同步方法中调用wait()和notify()?

时间:2013-06-10 20:02:36

标签: java multithreading thread-safety

我一直在为一个大学实验室建立一个简单的摇滚,纸张,剪刀游戏。 我有一个非常简单的服务器,当两个客户登录时启动游戏。 它的工作原理如下:

服务器创建游戏对象并等待玩家客户要求游戏。

一旦两个玩家请求游戏,服务器就会创建一个玩家1对象和一个玩家2对象,将游戏对象传递给他们的构造函数。

玩家在玩家对象上调用方法,然后在游戏对象上调用方法。 游戏对象中有同步方法。

每个玩家进行移动,存储在游戏对象中,然后游戏对象计算获胜者。

玩家对象在游戏对象中调用相同的方法,这一切都很好。但是我的一个朋友对我在任何方法中都没有调用wait()或notify()这一事实感到困惑。他已经介绍了他的实验室并通过了。他在同步方法中询问了wait()和notify(),但他说她的回答含糊不清,他仍然不确定,但为了以防万一,我应该把它们放进去。 那么交易是什么?我是否需要在同步方法中使用wait()和notify()?

另外,我读到Java虚拟机之间的synchronized不起作用,这是真的吗? 如果是这样,这对我的游戏有什么影响,同步做任何事情?

非常感谢。

3 个答案:

答案 0 :(得分:2)

wait()notify()是单个JVM中线程之间显式通信的机制。要大大过分简化,wait()意味着“轮到你了”,而notify()意味着“好的,我已经完成了”。你从不需要添加它们“只是为了安全” - 事实上这个想法绝对是荒谬的。

synchronized关键字主要用于确保所有线程都看到共享数据的相同有效视图;它本来要解决的问题不能在单独的JVM之间出现,所以在这种情况下它什么都不做就没问题。

答案 1 :(得分:0)

如果无法查看代码,我只能提供有关同步方法的一些基本帮助。同步用于确保两个线程不会同时尝试访问或更改资源,可能然后导致该资源处于不确定状态。

这是一个边缘情况,所以你的应用程序在运行数千次时可能不会出现任何问题,但有一次两个线程试图同时更改相同的值,你会得到一个奇怪的错误,它不会轻易再现。

答案 2 :(得分:0)

  

但我应该把它们放在以防万一。那么交易是什么?我是否需要在同步方法中使用wait()和notify()?

如果不了解有关代码的更多详细信息,我们无法回答此问题。当然你不应该“以防万一”添加它们。如果一个线程需要等待另一个线程通知它,那么是,你需要它们。如果你的算法没有线程相互通信,那么你就不需要它们了。

当两个线程需要通信时,通常使用

wait()notify()。例如,player2正在等待player1进行移动,因此player2线程调用move.wait();。一旦player1完成移动,player1线程调用move.notify();,这会导致player2线程继续运行。

您的线程可以通过多种不同的方式相互通信。他们可以共享一个BlockingQueue,因此player2线程可以调用queue.take(),它会在内部为您处理锁定和信令。

我真的很想知道你如何用一个共享的“游戏对象”编写一个线程游戏程序,而不会让线程相互等待。你说“每个玩家都会采取行动”但这听起来似乎需要在玩家之间进行某种协调。但是如果每个玩家的线程只是在等待用户输入,并且用户在他们看到之前玩家的移动之前不进行另一次移动,则可能是等待/通知由用户完成而不是由您的程序强制执行。

  

另外,我读到Java虚拟机之间的synchronized不起作用,这是真的吗?如果是这样,这对我的游戏有何影响,同步做任何事情?

如果您运行两个单独的JVM(2个不同的Java程序),则

synchronized不起作用。 synchronized关键字用于同步内存视图,并在多个线程在同一JVM中运行时为关键代码提供互斥锁。

例如,在您的游戏程序中,如果有两个线程使用某种共享Game对象,则应使用synchronized关键字来确保只有一个线程正在对其进行更改Game同时确保他们拥有Game状态记忆的最新版本。