我有一个多人网络游戏,我用Java编写,玩家连接到服务器并获得他们可以玩的“卡片”,每个玩家都有自己的线程中产生的服务来处理所有事情。 我想要做的是找出让服务器'暂停'的方法,直到所有玩家都已连接并达到服务中的相同点,这样游戏才能开始。
服务器产生如下线程:
for (int i = 1; i <= numPlayers; i++){
ArrayList<Card> playersCards = getPlayersCards(i-1);
Socket s = server.accept();
System.out.println("Player "+ i +" connected.");
Service service = new Service(s, playersCards);
Thread t = new Thread(service);
t.start();
}
然后我的服务:
public class Service implements Runnable {
private Socket s;
private Scanner in;
private PrintWriter out;
private ArrayList<Card> cards;
public Service(Socket aSocket, ArrayList<Card> cards) {
s = aSocket;
this.cards = cards;
}
public void run() {
try {
in = new Scanner(s.getInputStream());
out = new PrintWriter(s.getOutputStream());
out.println("Welcome to the Simple Stock Market Game.");
out.flush();
sendCards();
//AT THIS POINT THE SERVICE WOULD NEED TO wait for all players to connect
} catch (IOException e) {
e.printStackTrace();
} finally {
out.println("Thanks for playing the Simple Stock Market Game.");
out.flush();
}
try {
s.close();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("Player disconnected.");
}
private void sendCards() {
Gson gson = new Gson();
String cardsJSON = gson.toJson(cards);
out.println(cardsJSON);
out.flush();
}
}
现在我假设我可以通过该服务将有多少玩家,并等待那么多线程达到这一点? 不太确定,希望你们能帮忙!
答案 0 :(得分:2)
您可以使用java.util.concurrent.CountDownLatch,这正是您所需要的。
在创建服务的循环之前,使用预期的线程数(玩家)初始化它:
CountDownLatch playersLatch = new CountDownLatch(numPlayers);
然后在服务中:
playersLatch.countDown();
try {
playersLatch.await();
} catch (InterruptedException ex) {
//handle interruption
}
此外,您可能希望查看java.util.concurrent.CyclicBarrier,它类似但在等待线程释放后允许重用。
答案 1 :(得分:0)
如果你反复调用它,Phaser将是最好的解决方案,因为它以简单和可重用的方式组合了CountDownLatch和CyclicBarrier。对于一次性使用,CyclicBarrier就足够了(与Phaser相比性能略有提升)。
另外请记住,如果您使用这样的同步工具,则在出错时(在最终代码中)取消注册,否则所有剩余的方将被无限期停留。