简体   繁体   中英

How to implement SwingWorker in multithreaded Swing MVC client-server program?

I've created a battleShip online game that works on a client - server - client architecture. It uses TCP sockets to comunicate.

Server program is a very easy program, that creates it's own serverThread when a new client is connected.

The problem is in the client.

Client follows MVC architecture, where Model is represented by an Object shared between View and Controller.

View is where all GUI istances (with input listeners etc..) take place.

Controller is where takes place the server-client comunication over TCP sockets. NOTE: Server can send Packets to let Controller update GUI, and Controllers has several children-threads that make time-consuming tasks and then update GUI

Both View and Controller run on different Thread. Every GUI updating tasks run on EDT thanks to swingutilities.invokelater

The problem is that usually entire game works fine, but sometimes, with no possibilities to reproduce the error, the GUI freezes. I've read a lot of posts online about this question and I think the problem is that View, Controller and other threads, can update the GUI with no synchronization at all.

Anyway, what would be the best way to implement a SwingWorker in a program like this? Wherever there is the need to deal with GUI should i use a SwingWorker? and will it solve my GUI-freezing problem?

I am a bit confused on how SwingWorker should be implemented...

Thanks, and sorry for my bad english.

EDIT: After some experimentation, i found out that GUI usually freezes when a backgroundThread is trying to re-start a finished clip. When game starts it starts a clip (backgroundAudio), then i create a thread like this:

        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();  

the aim of this thread is to restart the clip if it is finished. I think the problem is in the order of clip.start and clip.setMicrosecondPosition, because if the put.setMicroSecondPosition as first, it doesn't freeze the GUI. But my question is: why should GUI get freezed if this thread is not on EDT?

Usually a SwingWorker should not be necessary in your Code, if you do all time consuming tasks in some daemon threads of you Controller.
For me your problem descriptions sounds like you are doing some major work in the context of the EDT. First thing to check would be in my eyes, the program parts that you run via invokeLater.
If you are starting, maybe a lazy evaluation, as you are already in the EDT, the exact same behavior as you described it in this thread would occur.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM