当前位置: 首页 > 知识库问答 >
问题:

等待具有相同服务的其他线程到达某个点

谯德佑
2023-03-14

我用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();    
    }

}

现在我假设我可以通过服务,将有多少玩家,并等待那么多线程到达该点?不太确定,希望你们能帮忙!

共有2个答案

金亦
2023-03-14

如果您反复调用它,Phaser将是最好的解决方案,因为它以简单且可重复使用的方式结合了CountDownLatch和CyclicBarrier。对于一次性使用,CyclicBarrier就足够了(与Phaser相比性能略有提高)。

此外,请记住,如果您使用这样的同步工具,则会在出现错误时注销(在最终代码中),否则所有剩余方都将被无限期地卡住。

田曜瑞
2023-03-14

您可以使用java.util.concurrent.CountDownLatch,这正是您所需要的。

在创建服务的循环之前,使用预期的线程(玩家)数量对其进行初始化:

CountDownLatch playersLatch = new CountDownLatch(numPlayers);

然后在服务中:

playersLatch.countDown();
try {
    playersLatch.await();
} catch (InterruptedException ex) {
    //handle interruption
}

另外,您可能想看看java.util.concurrent.CyclicBarrier,它类似,但允许在等待线程释放后重用。

 类似资料:
  • 首先,我决定让我的类阻塞(让消费者更容易使用,但对我来说可能更乏味)。而不是让使用者定义异步回调。这是一个好的设计模式吗?这样,用户可以获得预期的行为,但如果他们对线程被阻塞的时间不满意,则可以实现自己的多线程。 我有一个构造函数,它根据异步回调的结果在类中设置最后一个字段: 这不起作用,所以我使用了原子引用,并实现了一个阻塞循环,直到返回结果,如下所示: 这是阻止/检索结果的好方法吗?

  • 线程可以等待,直到其他线程释放访问同步块的锁。我想知道当其他线程访问同步块时,一个线程可以等待多长时间?什么时候它会知道另一个线程释放了锁?

  • 我做了几个线程转储,发现有16个线程在等待同一个锁,例如: “__ejb-thread-pool1”守护进程prio=6 tid=0x39657c00 nid=0x1c08在条件[0x3297f000]java.lang.thread.state:waiting(parking)在sun.misc.unsafe.park(本机方法)-在java.util.concurrent.locks.lock

  • 我有下面的docker-compose,在启动myprogram-app之前,我需要等待jhipster-registry服务启动并接受连接。 我尝试了 healtcheck 方式,遵循官方文档 https://docs.docker.com/compose/compose-file/compose-file-v2/ 但在运行<code>docker compose up</code>时,我遇到了

  • 我现在的码头工人。yml- 我的码头工人。yml文件包含2个服务。我已经指定postgrasdb服务在python应用程序服务使用之前启动,但是docker没有按照指定的顺序运行服务。如何让postgrasdb服务在python应用程序服务之前运行?我正在运行命令。

  • 有时我看到一些线程还没有完成他们的工作,服务杀死那个线程,我怎么能强迫服务等待,直到线程完成他们的工作? 这是我的代码: 我看到了一些例外。future.is完成())块。我怎么能确保每一个未来是当执行者服务关闭?

  • 我正在使用Spring 4.3.8。发布Java7。我想创建一个线程工厂来帮助管理应用程序中的某些工作人员。我像这样声明我的线程工厂 但是,我在线程上“加入”有困难。也就是说,我想在继续某个任务之前等待所有工作完成,所以我有 我的线程池是这样执行的 然而打印出来的是 所以很明显我没有等待。等待我的线程完成工作的正确方法是什么?

  • 我们在应用程序中使用了Stomp、SpringBoot和WebSockets。服务器应用程序执行以下操作:1)生成要推送给用户的消息;2)接受WebSocket连接;3)将消息推送给ActiveMQ stomp Broker。线程转储显示了大量与simpMessagingTemplate convertAndSendToUser API调用相关联的等待线程。 应用程序的两个实例在云中运行。该应用程