I know that this problem is caused by the sleep or wait calling on the main thread and that the answer on how to solve this will be to put the method into a seperate thread and then make that thread sleep. But the code is a mess and don't really have the time to sort it out and split it up into separate threads and was wondering if there is any other way of doing this? Even if it is not the cleanest or most common practice for working with GUIs. I only need about a seconds pause from the method.
You can't do it without creating a separate thread. Creating a thread in Java is easy. The only thing to pay attention to is that you can only touch the UI through the main thread. For this reason you need to use something like SwingUtilities.invokeLater().
It is not possible to sleep on an event thread and not cause a GUI freeze. However in Swing, the event thread is created and managed behind the scenes - you main thread (the one originating from main() method) is not the event thread.
So, you can safely sleep on your main thread.
Using a separate thread for the code is your only solution. Every action started by the Swing thread must be delegated to a separate thread if it would otherwise block the GUI.
I wrote a super simple delay function for java that doesn't let your GUI freeze . It has worked everytime i have used it and i guess it will work for you too.
void Delay(Long ms){
Long dietime = System.currentTimeMillis()+ms;
while(System.currentTimeMillis()<dietime){
//do nothing
}
}
For eg : To delay a thread by 5 millisecods use Delay(5L)
And where would one declare this thread. Please bear in mind any, any reference to a function that contains thread sleep will cause the main thread to pause. Because the main thread will have to wait the the sub thread to pause.
The reality is that threads don't realy work as seperate independant thread because a thread must be started from another thread. In other words if you are creating desktop application, and even if you don't work with other threads, your application is a one threaded application. Now if you start working with threads & putting them to sleep, you will soon find out that that you won't be able to do anything else in the application. No & no the other threads won't even run because they are waiting the first thread to finish sleeping. Why is this? Cause the thread are sub threads of the main thread and it is the main thread that is waiting for that sleep sub thread to wake up. You can't design a threadless application either as java is single main threaded application. Any, yes any, thread further defined in your application always runs inside in the main thread.
Unless somebody can prove me wrong, you obviously whould never pause your main thread as this would lock up your app. However as soon you define another thread and suspend it with sleep() this also locks up your app as the thread was defined in subclass of the main application and therefore the main thread.
So to put a very very long story to bed, pausing a user defined thread, is almost exactly the same as if your called the Thread.sleep() for anywhere in your app, it
pauses the entire application.
Related
How does scheduler work here ? Does it create a new thread in the background and execute Run method in the main thread like a callback. ? . When run method is getting executedl, is it belong to the main thread?
classA implements Runnable
{
public void Run()
{
System.out.println(Thread.currentTread().getName());
}
public static void main(String args[])
{
Thread.currentThread().setName("Main");
ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
scheduler.scheduleAtFixedRate(this, 250, 250, TimeUnit.MILLISECONDS);
}
}
Thanks.
How does a SingleThreadScheduledExecutor work ?
It creates a thread pool that will at most contain one thread. This makes sure that only one task at a time (that is scheduled on this executor) will run.
Tasks run in the executor's single thread, not on the thread that has submitted them.
Can you make it so that the method runs on the "main thread" ?*
Well you can "make" anything, right ? But not with an ExecutorService, it is designed to work with its own thread.
How so then ?
Basically, either you're in an environment that provides everything to you (UI applications in Swing do for example), so check if this is your case (Swing has the Event Dispatch Thread). Either you nedd some work. So I'd first suggest you make sure you really NEED to work in the main thread before going on and doing this work.
What does this work involve ?
Without any special work, your main thread execute codes that is an ininteruptible flow of satements. They are written once, nobody can "inject" code into your main thread (well, unless you get really messy with your memory, which you can, but that is not something one usually do).
So your main thread is busy doing task A, then B, then C, then D in order, as fast as it can (or is allowed to). You can not inject "task E" in the middle of this flow.
Metaphorically, this would be the equivalent of chossing a random line in your code, and add statements of another method right there : crash guaranteed (what is the context, what is the stack, what variables exist at this particular line, and with which value : unpredictible). This can not happen.
And so, even if task A is "create a task to execute in 4 seconds", what will happen is : in another thread you get notified in 4 seconds that the timer expired, and this other thread will get to decide what to do, because the main thread is in the middle of doing "task B", and there is nothing else it can do.
So basically... it can't be done ?
Oh yes, it can. But you have to make "task A" (or B, or C), special for it to work. You have to design your main thread to periodically "wait" for events that come from outside.
And there is not a great many deal of ways to do that : periodically do something. You have to make your main thread performe an "loop". This pattern is called a run loop. Many many UI frameworks run this way.
What happens is that :
you create a Queue, and make it globally accessible (Singleton pattern, for example) to your program. The goal of this queue will be to receive all the work units that the main thread is supposed to execute.
Upon start, you make your main thread spawn a secondary thread that will be responsible to continue the initialization process and life of your application after step 3
you make your main thread enter an infinite loop waiting for new events from the queue
With your "secondary" thread, you can then do anything you like, including setting your first timer. When the timer fires, it should send the work to be performed (say a Runnable instance ?) to the queue. The main thread will pick up that a run the runnable inline.
Is that efficient ? Waiting for events ?
Yes it can be. If you use well purposed objects (ConcurrentQueue ?) that are designed for concurrency, you do not actually perform work and waste resources while waiting. What happens under the hood is that threads are "signaled" by the operating system that new units are available. So it's not an infinite loop where you say "is there something to do ? If yes > do it, if no > wait three seconds". It's "Signal me when there's something to do".
I do not know of any JAR / lib or tool or best practice to actually implement this. Most of the times, either the environment provides this (Swing's ìnvokeLater), either I did not need this kind of things. So I know how this theoretically works, but I guess this is surprisingly difficult to actually implement right.
Wikipedia's entry for this pattern : http://en.wikipedia.org/wiki/Event_loop.
In game programming, one often have a "game loop" that is an equivalent pattern
I had a quick question, in Java, is it better to let a thread run continuously after it is done being used, or is it better to try and .interrupt() the thread?
My thought is this: Lets say I create threads by a loop so that I can have 100 threads all doing a separate process that does not interrupt the GUI (on the main thread), then the process is finished on all of the threads. Do I stop the threads, or do I just let them continue being open, even though they are not technically doing anything?
My guess is that it would be best to kill the threads so they do not take any resources from the rest of the program. Any ideas?
When a thread has "finish processing", i.e., exits from the run method, the thread will terminate itself and there's no need to interrupt.
I think title itself says what the my question is...
AFAIK, in Java, when work of a Thread is completed i.e. run() method has completed executing, Thread itself will finish and dies.
So, When my Activity(I mean UI) is idle for a long time, what the UI thread will do? does it sleeps? or does it do any other work?
Thanks to all...
I believe the question is not really about Java threads in general, but about the Android "main thread" (also called the "UI thread").
To quote from the JavaDoc for the Android Handler:
When a process is created for your application, its main thread is
dedicated to running a message queue that takes care of managing the
top-level application objects (activities, broadcast receivers, etc)
and any windows they create. You can create your own threads, and
communicate back with the main application thread through a Handler.
This is done by calling the same post or sendMessage methods as
before, but from your new thread. The given Runnable or Message will
then be scheduled in the Handler's message queue and processed when
appropriate.
In other words: The main thread is responsible for dequeuing messages/runnables from a queue and processing them. That main thread is blocked while the queue is empty (since there is nothing for it to do). If you use a Handler that was created in the main thread, that Handler's messages and runnables will actually be added to the same queue used by the main thread. Normally, the main thread will run as long as the process does.
Note: An Android app can actually have multiple processes, and each one will have its own main thread. However, most Android apps will only have one process (and therefore one main thread).
I'm working with a GUI and I'm using
Thread.sleep();
in some of the classes, and I'm wondering if I need to create a separate Thread for my Main class (the GUI class), or if each class has a separate Thread by default. Note, the reason that I bring up Thread.sleep(); in the first place is that when working with GUI's Thread.sleep(); pretty much freezes your GUI. Anyways my main question is do I need to create a separate Thread for my Main class or if each class has a separate Thread by default.
Thread.sleep() is a static method of Thread class. Hence, whichever class you place in a method, during runtime, if a thread call flow encounters this class method where Thread.sleep() in invoked, the thread will be blocked for that amount of time.
Your Question:
Anyways my main question is do I need to create a separate Thread for my Main class or if each class has a separate Thread by default.
each class has a separate Thread by default -- INCORRECT Statement
-- Thread class is not inherited by every class
-- In normal sense, Thread is a call flow. It executes whichever class it encounters thru its method calls.
-- Class and Thread are 2 separate concepts.
---- Class is a definition of an entity,it cannot run by itself, it can be loaded, instantiated with data, method calls can be done and garbage collected.
---- Thread is an execution entity at run-time.It can be started, runnable, blocked, stopped. To support this concept, Java has provided Thread class or Runnable interface to extend/implement respectively.
do I need to create a separate Thread for my Main class?
-- your mainclass will be executed in a MainThread which is instantiated and started by your JVM.
-- It is better to define a seperate user-defined Thread to start your GUI.
-- If either in the MainThread (or) user-defined Thread, if it encounters Thread.sleep() during call flow, that particular thread will be blocked.
One more thing, your question is not clear on your need for usage of Thread.sleep(). You just have given a reason of the resultant usage of it but not the need for usage.
From javadoc for Thread:
Causes the currently executing thread to sleep (temporarily cease
execution) for the specified number of milliseconds, subject to the
precision and accuracy of system timers and schedulers. The thread
does not lose ownership of any monitors.
Don't mind that the sleep() method is static, it is executed for the thread in which you call it. So if you call it from GUI, it puts your main UI thread into sleep, hence freezing UI completely.
by default the program does not have more than one thread. there should be only one class which has a main method. it does not matter it is a ui application or any other type of application.
please post the details in what scenario you want to use the sleep function.
When a java class is created automatically 3 thread are created by-default with it.
1.Main Thread
2.Thread Scheduler
3.Garbage Collector thread
Please watch this explanatory video to understand what a Thread actually is.
In this example the Thread is the music box, your code is the sheet of paper, and the processing time granted to a thread is the rotation of the handle.
So your main-class code (sheet-of-paper) is inserted into a thread (music-box) generated by the JVM and execution is started (handle rotates). Once you call sleep(1000) "rotations of the handle" is paused for 1 second, and so is the execution of your code. Thread.sleep() is just a short-cut to Thread.getCurrentThread().sleep().
If you now have several threads (music-boxes), you can of course pause one while another still runs. So if you have a main thread and a GUI thread, you can pause the main thread and your GUI will work fine (unless it actually tries to access the main thread). If you however pause the GUI thread, it will appear to be frozen.
I've been reading a bit about concurrency (which gives me a headache).
I understand you can set a task to run on the EDT from the main thread using:
SwingUtilities.invokeLater
but can you set a task to run on the main thread from the EDT?
As in:
Thread mymainthread=Thread.currentThread();//<referring to the thread that initially kicks off public static void main
public void mousePressed(MouseEvent e){ //queue a task to run on mymainthread }
Can it be done? Is it a bad idea?
The other question on SO similiar to this (here) talks about creating a new thread but wouldn't it be safer and simpler to keep using the main if I was aiming for a single thread (+EDT) application? .......or maybe I've got this all wrong.
EDIT: What I should have explained: I wanted to create objects that would communicate with each other on the main thread (running in a slow loop) so I didn't want any of them be instantiated on a different thread, edt or otherwise.
but can you set a task to run on the main thread from the EDT?
I think you are confused on what EDT is. Swing and many other frameworks use a technique called thread-confinement.
In order to guarantee thread-safety, all actions are executed from a single thread. This thread in Swing is called Event Dispatcher Thread.
This thread has a queue and executes all tasks from that queue sequentially one at a time, at the same thread. This is why your tasks should be short in order not to block the UI.
So when you use EDT you are essentially passing a task to its queue from your thread and EDT will eventually execute it.
What you can do is put a task on the EDT queue which spawns a thread to be executed on separate thread. If you want to use your current thread for some reason as the background thread perhaps you could but why would you need that? The most straightforward way is just to submit a runnable to run as part of some background thread e.g. part of a pool
You can create your own event loop to do thread-confinement. This would allow you a separate single thread which would behave like the EDT. Be careful not to share [effectively] mutable objects between the two threads simultaneously.
Implementation can be as simple as a while loop with a BlockingQueue. You can go slightly higher level by getting an ExecutorService from java.util.concurrent.Executors.newFixeThreadPool(1).