Java Multiple Threads Difficulty - java

At the moment I have a simple Stopwatch code that uses System.currentTimeMillis. My program however freezes when I try to get it to update the JTextField that holds the number of seconds that has passed, it freezes. I've searched around and if I've understood it right I can't have the same "thread" run the infinite loop and the GUI. I am a fairly unexperienced programmer and wondering if threads is something I should even try to grasp/learn/implement.

You should use a different Thread for your business code than the AWT/Swing thread that is updating the UI. If you block the AWT/Swing Thread, the UI will be blocked as well.
Use a new Thread for your countdown and update the UI from the AWT thread, which can be done by SwingUtilities.invokeLater, see https://docs.oracle.com/javase/7/docs/api/javax/swing/SwingUtilities.html#invokeLater%28java.lang.Runnable%29

Threads may look scary at first, but it's not as scary as you think. it is also a good place to start when learning extends and implements. Take a look here for some simple examples to get you started: https://docs.oracle.com/javase/tutorial/essential/concurrency/runthread.html

Related

The function call blocks GUI from updating in java

I am currently working in a implementing a quoridor game in java , using AI game-playing algorithms. After the "human" clicks to make his move , the gui needs to be updated and the AI start thinking.
I have something like this inside the panel:
public void mouseClicked(MouseEvent e)
{
gameBoard.executeMove( movePawn );
repaint();
gameboard.callAi();
}
After I call the funtcion callAi() , I get into a loop that is consuming too much time to finish. The gui on the other hand freezes , it doesnt update , even thought the repaint method is called before the AI "start thinking". I tried to put a delay before I call the AI , but it was not working. I wrote this one:
try
{ TimeUnit.MILLISECONDS.sleep(5);}
catch{}
What can I do to solve this one ? Maybe it has something to do with threads , but I am not too friendly with threads in Java.
I would highly recommend reading up on what the EDT (Event Dispatch Thread) is.
Java Event-Dispatching Thread explanation
One of the answers does a good job explaining it. Quick TLDR: Basically one of the reasons the GUI freezes is because of the AI method you included on the EDT (I can't say for certain about the gameBoard.executeMove(...) method). EDT is meant for updating the GUi, not running methods that take a lot of compute time.
Get the game logic code out of the GUI and into the main thread/new thread (not the EDT). If you absolutely need game logic inside the EDT then make a new Thread in the EDT, have it do its game calculations, and finally use Swing.Utilties.invokeLater(...) method to update the GUI.
Maybe it has something to do with threads , but I am not too friendly with threads in Java.
Definitely want to get familiar with threads when you are making a game, specially the EDT.
You should use a SwingWorker to do the AI work on this. All the updating and processing happens on a single thread within Swing so if you block that then you will freeze the UI.
https://docs.oracle.com/javase/tutorial/uiswing/concurrency/worker.html

What is Java's interface equivalent of Thread.sleep()?

I'm programming a robot that uses an interface with buttons and a text box and stuff, and I know that if you are using
Thread.sleep();
then it will pretty much break your interface. I know that
Thread.sleep();
pretty much just pauses your current thread and resumes it after an allotted amount of time. I need to have a slight pause in my program without breaking my interface, such as an interface equivalent of
Thread.sleep(1000);
I've looked for hours and I can't find anything to create a slight pause in one part of your program while maintaining an interface. Also I don't know about multithreading so please explain stuff in as much detail as possible. Thanks in advance for helping me!
Everything in a Java Swing user interface runs on a single, special thread (the Swing thread or "event dispatching thread"). If you block this thread with a Thread.sleep() then your user interface stops responding.
To be able to sleep (i.e. deliberately delay some processing) without blocking the user interface, your program may need to run on multiple threads. I suggest you take a look at the Java tutorial on this topic. Multithreading is a fairly advanced topic that can't really be summarised in a short answer.
It's not clear what you are trying to achieve with your sleep - if you just want some action to be triggered at a future time, then the Timer class may do what you need without needing extra threads.
There are also some helper classes in the Java libraries for running tasks on other threads in a GUI application.

Java Event-Dispatching Thread explanation

I've recently started learning and exploring the basics of GUI programming in Java.
Having been programming for a while I have only done backend work or work and as a result the closest I've gotten to user interfaces is the command console (embarrassing I know).
I'm using Swing and as far as I can gather that means by extension I am also using AWT.
My question is based on this piece of code:
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new frame.setVisible(true);
}
} );
I have been researching this for a while as I wanted to fully understand this strange piece of code and have come across the term 'Event-Dispatching Thread' multiple times. Correct me if I'm wrong but as I understand it; it has to do with using multiple threads and how Java Swing interprets those threads. I gather as well that the above code is used to make sure all the threads are 'safe' before it creates the window, hence the invokeLater?
I have read that:
"You can only call methods that operate on the frame from the Event-Dispatching Thread"
and that only under certain circumstances can you call methods that operate on the frame from the main method.
Can somebody please clarify to me what exactly the Event-Dispatching Thread is?
How it relates to multiple threads of execution and how those threads are not safe to be called from the main method? Also why do we need this invokeLater?
Can we not just create the window as any other object?
I've hit a bit of a road block in my research as I'm not grasping these relations and ideas.
A side note is that I like to base my knowledge on in-depth understanding as I believe this leads to the best overall outcome and as a result the best programs. If I understand in-depth how something works then you can use the tips and tweaks effectively rather than just parroting them back in to code, so please don't be afraid to give me some extra in-depth explanations and broaden my knowledge.
Thank you.
The event dispatch thread is a special thread that is managed by AWT. Basically, it is a thread that runs in an infinite loop, processing events.
The java.awt.EventQueue.invokeLater and javax.swing.SwingUtilities.invokeLater methods are a way to provide code that will run on the event queue. Writing a UI framework that is safe in a multithreading environment is very difficult so the AWT authors decided that they would only allow operations on GUI objects to occur on a single special thread. All event handlers will execute on this thread and all code that modifies the GUI should also operate on this thread.
Now AWT does not usually check that you are not issuing GUI commands from another thread (The WPF framework for C# does do this), meaning it's possible to write a lot of code and be pretty much agnostic to this and not run into any problems. But this can lead to undefined behavior, so the best thing to do, is to always ensure that GUI code runs on the event dispatch thread. invokeLater provides a mechanism to do this.
A classic example is that you need to run a long running operation like downloading a file. So you launch a thread to perform this action then, when it is completed, you use invokeLater to update the UI. If you didn't use invokeLater and instead you just updated the UI directly, you might have a race condition and undefined behavior could occur.
Wikipedia has more information
Also, if you are curious why the AWT authors don't just make the toolkit multithreaded, here is a good article.
EventDispatchThread (EDT) is special thread reserved only for Swing GUI and *Swing's related events e.g. create/change/update Swing JComponents, more for asked questions here and here
all output to the GUI from BackGround Tasks, Runnable#Thread must be wrapped into invokeLater(), from synchronized Objects into invokeAndWait();

To use or not to use a SwingWorker versus a regular Thread

I have a start and stop button. I want to be able to start and stop a task as many times as the user wants to. I was able to get this working properly with a regular thread by doing a wait() when the stop button was pushed and then a notify() when the start button was pushed to start the thread again. This worked great. However... I extended thread. My boss told me to never extend thread and that I should use a SwingWorker. But I noticed that a SwingWorker can only be executed once. Or can it be executed more than once in the same session..?? Can somebody help me in the right direction here?
You very rarely need to extend Thread. What you should do is pass a Runnable to a Thread constructor.
For my tastes SwingWorker adds too much coupling to code, and should be left to demos where it works very well.
You can just create a new instance of your SwingWorker each time you want to run the logic. Personally, I don't see much benefit to SwingWorker for your problem as you described it. Not to say it won't do fine...
You don't need a SwingWorker for what you doing. SwingWorker is used for cases when you have to run something in background thread, update your GUI (like progress) without locking i down.
What you did already is fine.

What is the event dispatching thread?

I know what "thread" means and if I understand the event dispatching thread (EDT) as
"just a thread", it explains a lot but, apparently, it does not explain everything.
I do not understand what is special about this thread. For example I do not understand why we should start a GUI in a the EDT? Why the "main" thread is bed for GUI? Well, if we just do not want to occupy the main thread why we cannot start GUI just in "another thread" why it should be some "special" thread called EDT?
Then I do not understand why we cannot start the EDT like any other thread? Why we should use some special tool (called invokeLater). And why GUI, unlike any other thread, does not start immediately. We should wait until it is ready to accept our job. Is it because EDT can, potentially execute several task simultaneously?
If you decide to answer this question, could you pleas use a really simple terminology because otherwise, I am afraid, I will not be able to understand the answer.
ADDED:
I always thought that we have one "task" per thread. So, in every thread we execute a predefined sequence of commands. But it seems to me that in the event dispatching thread we can have sever task. Well, they are not executed simultaneously (thread switches between different task but there are still several task in one thread). Is it right? For example there is one thread in the EDT which display the main window, and then additionally to that we sent to the EDT another task which should update one of the window components and EDT will execute this new task whenever it is ready. Is EDT differ from other threads in this way?
The event dispatching thread is the thread that handles all GUI events and manages your Swing GUI. It is started somewhere in the Swing code if you have any GUI in your program. The reason it is done behind the scenes is because of simplicity - you do not have to bother with starting and managing an extra thread by yourself.
Regarding the fact that you have to update your GUI with invokeLater() it is because of concurrency issues. The GUI can be modified only from one thread because Swing is not thread safe(it is worth to note that most of toolkits are not thread safe, there is a nice article that gives some ideas why). This is why you have to submit all GUI updates to run on EDT.
You can read more on concurrency in Swing and event dispatching thread in Sun tutorial on concurrency in Swing. Also, if you would like to see how this could be done in a different way you might like to check out SWT toolkit. In SWT you have to manage EDT by yourself.
I always thought that we have one
"task" per thread. So, in every thread
we execute a predefined sequence of
commands. But it seems to me that in
the event dispatching thread we can
have sever task. Well, they are not
executed simultaneously (thread
switches between different task but
there are still several task in one
thread). Is it right? For example
there is one thread in the EDT which
display the main window, and then
additionally to that we sent to the
EDT another task which should update
one of the window components and EDT
will execute this new task whenever it
is ready. Is EDT differ from other
threads in this way?
No, the EDT is not fundamentally different from other threads. And "task" is not a good word to use, because it could be confused with OS-level processes (which are also often called task). Better use Runnable, the interface used to give code to the EDT to execute via invokeLater().
The EDT is basically connected to a queue of things it has to do. When the user clicks a button on the GUI, a Runnable that notifies all listeners attached to the button goes into the queue. When a window is resized, a Runnable doing revalidate&repaint goes into the queue. And when you use invokeLater(), your Runnable goes into the queue.
The EDT simply runs an endless loop that says "take a Runnable from the queue (and if it's empty sleep until you're notified that it's not) and execute it.
Thus, it executes all those little Runnable pieces of code one after another, so that each of them basically has the GUI all to itself while it runs, and doesn't have to worry about synchronizing anything. When you manipulate the GUI from another thread, this assumption is broken, and you can end up with the GUI in a corrupted state.
What is the EDT?
It's a hacky workaround around the great many concurrency issues that the Swing API has ;)
Seriously, a lot of Swing components are not "thread safe" (some famous programmers went as far as calling Swing "thread hostile"). By having a unique thread where all updates are made to this thread-hostile components you're dodging a lot of potential concurrency issues. In addition to that, you're also guaranteed that it shall run the Runnable that you pass through it using invokeLater in a sequential order.
Note that it's not just that you're dodging the concurrency issue: you must respect Sun's guidelines regarding what must and what must not be done on the EDT or you'll have serious problems in your application.
Another benefit is that some Swing components tend to throw unwanted exceptions and when this happen they're automagically dealt with and won't crash the EDT (AFAIK if you really manage to kill the EDT it is automagically restarted).
In other words: you don't have to deal with all the broken Swing components and the exceptions they throw yourself: the EDT is taking care of that (just take a look at the countless Swing bugs throwing exceptions in Sun's bug parade, it's fascinating... And yet most apps keep working normally).
Also, by doing only what's mandatory in the EDT allows the GUI of your app to stay "responsive" even tough there may be tasks running in the background.
The important thing to remember is that Swing classes are not thread-safe. This means that you always should call Swing methods from the same thread, or you risk getting weird or undefined behavior.
So the solution: only call Swing methods from a single thread. This is the EDT thread - it's not special in any way other than that it is the thread designated to call swing methods from.
Now you may ask why are Swing methods not thread safe? After several unsuccessful attempts, GUI toolkit designers discovered that it's inherently impossible to design a thread-safe GUI toolkit. Too often events are passed in opposite directions (input events from bottom to top, application events from top to bottom) which always leads to deadlocks. So that's just the way it is.

Categories

Resources