Как реализовать SwingWorker в многопоточной клиент-серверной программе Swing MVC? - PullRequest
0 голосов
/ 13 октября 2019

Я создал онлайн-игру BattleShip, которая работает на архитектуре клиент-сервер-клиент. Для связи используются сокеты TCP.

Серверная программа - очень простая программа, которая создает собственный serverThread при подключении нового клиента.

Проблема в клиенте.

Клиент следует архитектуре MVC, где Модель представлена ​​объектом, совместно используемым между представлением и контроллером.

Представление - это место, где все объекты GUI (с входными прослушивателями и т. Д.).).

Контроллер - это место, где происходит соединение сервер-клиент по TCP-сокетам. ПРИМЕЧАНИЕ. Сервер может отправлять пакеты, чтобы позволить контроллеру обновлять графический интерфейс, и у контроллеров есть несколько дочерних потоков, которые выполняют трудоемкие задачи, а затем обновляют графический интерфейс

И представление, и контроллер работают в разных потоках. Все задачи по обновлению GUI выполняются на EDT благодаря swingutilities.invokelater

Проблема в том, что обычно вся игра работает нормально, но иногда, без возможности воспроизвести ошибку, GUI зависает. Я прочитал много сообщений в Интернете об этом вопросе, и я думаю, что проблема в том, что View, Controller и другие потоки могут обновлять GUI вообще без синхронизации.

В любом случае, что было бы лучшим способом? внедрить SwingWorker в программу, подобную этой? Везде, где есть необходимость иметь дело с GUI, я должен использовать SwingWorker? и решит ли это мою проблему с заморозкой в ​​GUI?

Я немного запутался в том, как следует реализовать SwingWorker ...

Спасибо, и извините за мой плохой английский.

РЕДАКТИРОВАТЬ: После некоторых экспериментов я обнаружил, что GUI обычно зависает, когда backgroundThread пытается перезапустить законченный клип. Когда игра начинается, она запускает клип (backgroundAudio), затем я создаю поток, подобный этому:

        thread_backgroundAudio = new Thread() {
            public void run() {
                System.out.println("THREAD CLIP->"+SwingUtilities.isEventDispatchThread());
                do { 
                    if(clip.isActive())
                        do {
                            if(!clip.isRunning() && !(clipWINNING.isActive()) && !(clipLOSING.isActive()) && !(clipLOSING.isRunning()) && !(clipWINNING.isRunning())) {

                                if(playMusic) {
                                    System.out.println("starto la clip nel thread");
                                    clip.start();
                                    clip.setMicrosecondPosition(0);
                                    break;
                                }
                            }
                        }while(playMusic);
                }while(true);
            }
        };
        thread_backgroundAudio.start();  

Цель этой темы - перезапустить клип, если он закончен. Я думаю, что проблема в порядке clip.start и clip.setMicrosecondPosition, потому что если поставить .setMicroSecondPosition в качестве первого, это не замораживает графический интерфейс. Но мой вопрос: почему GUI должен зависать, если этот поток не на EDT?

1 Ответ

0 голосов
/ 13 октября 2019

Обычно SwingWorker не требуется в вашем коде, если вы выполняете все трудоемкие задачи в некоторых потоках демона вашего контроллера.
Для меня ваши описания проблем звучат так, будто вы выполняете какую-то основную работу в контекстеEDT. Первое, что нужно проверить, будет в моих глазах, части программы, которые вы запускаете через invokeLater.
Если вы начинаете, может быть, ленивая оценка, как вы уже находитесь в EDT, точно такое же поведение, как вы описали это в этомнить произойдет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...