Я создал онлайн-игру 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?