3

我一直在为大学实验室的两个服务器客户端构建一个简单的石头剪刀布游戏。我有一个非常简单的服务器,当两个客户端登录时启动游戏。它是这样工作的:

服务器创建一个游戏对象并等待玩家客户端请求游戏。

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

玩家调用玩家对象上的方法,这些方法又调用游戏对象上的方法。游戏对象中包含同步方法。

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

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

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

非常感谢。

4

3 回答 3

2

wait()并且notify()是在单个 JVM 内的线程之间进行显式通信的机制。过于简单化,wait()意思是“轮到你了”,notify()意思是“好的,我已经完成了”。你永远不需要添加它们“只是为了安全”——事实上,这个想法绝对是荒谬的。

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

于 2013-06-10T20:05:16.780 回答
0

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

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

于 2013-06-10T20:11:06.963 回答
0

但我可能应该把它们放在以防万一。那么有什么关系??我需要在同步方法中使用 wait() 和 notify() 吗?

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

wait()并且notify()通常在两个线程需要通信时使用。例如,player2 正在等待 player1 移动,因此 player2 线程调用move.wait();. 一旦 player1 完成他的移动,player1 线程调用move.notify();这导致 player2 线程继续运行。

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

我确实想知道如何编写一个具有共享“游戏对象”的线程游戏程序,而无需线程相互等待。您说“每个玩家都行动”,但这听起来需要玩家之间进行某种协调。但是,如果每个玩家的线程只是在等待用户输入,并且用户在看到前一个玩家的动作之前不采取另一动作,那么等待/通知可能是由用户完成的,而不是由您的程序强制执行的。

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

synchronized如果您正在运行两个单独的 JVM——2 个不同的 Java 程序,则不起作用。当多个线程在同一个 JVM 中运行时,该synchronized关键字用于同步内存视图并在关键代码周围提供互斥锁。

例如,在你的游戏程序中,如果有两个线程在处理某种共享Game对象,它们应该使用synchronized关键字来确保一次只有一个线程GameGame状态存储器的最新版本。

于 2013-06-10T20:22:29.657 回答