开发者

Java thread issue

开发者 https://www.devze.com 2023-02-25 00:05 出处:网络
I\'m working on an application in Java that is required to update its results every second until it is stopped. For 30 seconds it will call a certain set of methods each second, then another set for t

I'm working on an application in Java that is required to update its results every second until it is stopped. For 30 seconds it will call a certain set of methods each second, then another set for the next 30 seconds, then the first set again and so on. Since I want to be able to stop and restart the calculations that are performed in the background whenever I want, I've made a GUI and a couple of buttons to start and stop the new thread, as well as a means to display the results every second.

The problem I've run into is that once the new thread is started I can't switch back to the GUI until it is completed, and since the thread will keep going until I tell it to stop, I end up not being able to exit an infinite loop. Could I fix this by placing the GUI in a thread of its own so that both threads are run at the same time? And if so, how would I go about doing that from inside the GUI?

I'm working with more than one class so I don't want to post irrelevant stuff.

public class GUI extends javax.swing.JFrame implements Runnable{
    Graphics g;
    Threads thread = new Threads();
    private void startButtonActionPerformed(java.awt.event.ActionEvent evt) {
         thread.run()
    }
    [..]
    private void stopButtonActionPerformed(java.awt.event.ActionEvent evt) {
         thread.stop()
    }
}
public class Threads implements Runnable{
boolean opened=false;
road first = new road();
public void run() {
    opened=true;
    first.standardInitializati开发者_如何学Pythonon();
    while(opened){
        for(int i=0; i<30 && opened; i++){
            try {
                first.redLightAction();
                System.out.println("cars: " + first.firstLight.cars);
                Thread.sleep(1000);
            } catch (InterruptedException ex) {
                Logger.getLogger(Threads.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        for(int i=0; i<30 && opened; i++){
            try {
                first.greenLightAction();
                second.greenLightAction();
                System.out.println("cars: " + first.firstLight.cars);
                Thread.sleep(1000);
            } catch (InterruptedException ex) {
                Logger.getLogger(Threads.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }
}
public void stop(){
    opened=false;
}

}


Yes, your GUI should be in its own thread(s).

You arent using a Thread. You are using a custom class that implements Runnable. Runnable != Thread. You want to do this instead:

Thread thread = new Thread(new Threads());

When you want to run it, use

thread.start(); // not thread.run()!!

Notice that I am passing in your Runnable to a real Thread. I would suggest renaming your Threads class to something more specific.

So, the way you have it setup now, you are just running your Runnable in the same thread as your GUI. With the the above code, you will have spawned a new thread for execution.


Yes, any non-gui activites (particularly long-running tasks) should be run on a new thread.

See a description of the "EDT", Swing's GUI thread: http://en.wikipedia.org/wiki/Event_dispatching_thread

You can use SwingUtilities' static methods to facilitate switching between EDT and other threads ... http://download.oracle.com/javase/6/docs/api/javax/swing/SwingUtilities.html

See invokeLater(Runnable) , isEventDispatchThread(), and others, to get you started ...


The GUI is updated on the Event Dispatch Thread. As you have an unresponsive UI, the EDT thread is not performing any work. This could be because:

  • the background work is not being done on a separate thread, but actually on the EDT
  • you are successfully creating a new background thread, but instead of letting it run asynchronously, you are waiting for it to complete.

You can't run the GUI on another thread - swing must run on the thread created by the system - the Event Dispatch Thread.

EDIT: more code added. you need thread.start() not thread.run(). The start method is the one that actually causes a new thread to start executing (which then calls the run() method). When you call the run() method directly, it's just a regular method call and executes on the calling (GUI) thread, hence the UI is blocked.


Swing is NOT thread-safe. Swing using something called the Event Dispatch Thread (check out mdma post for a quick introduction), and you can find a good tutorial here. Swing was not meant to be run with threads but you can model almost everything you can do with threads with the Event Dispatch Thread, except (big point here), it will not be concurrent.


The exact solution depends on exact details of what you have to do and whether you have to update GUI.

From what I read, I can suggest for you to implement a sort of a game loop. Since I understand you would want to simulate the traffic and present it to a user. Then such game loop would, every its iteration, first do all the calculations and update your objects finally displaying new state onto the screen. This is not a simple task and I am afraid you should familiarise yourself with concurrency and synchronization of code in Java.

public void run()
{
    long startTime = System.currentTimeMillis();
    long currTime = startTime;
    isRunning = true;

    while(isRunning)
    {
        long elapsedTime = System.currentTimeMillis() - currTime;
        currTime += elapsedTime;
        update(elapsedTime);
        gameRender();
        paintScreen();
        try
        {
            Thread.sleep(1000);
        }catch(InterruptedException ex)
        {
            Logger.getLogger(GamePlayPanel.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
} 

You would have a skeleton like the above one in your class which implements Runnable, then you create a thread giving it your class as the parameter, finally you start it.

More reading about game building can be found http://www.brackeen.com/ the guy published a fantastic book about games in Java, highly recommended.

EDIT1: From the code I observe you are creating the Thread fine but you should start it using the start method of the Thread not run. ---> why is explained by @Brad.

Good luck, Boro.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号