I am having a problem understanding the differences between some kinds of making a tread loop.
one is (a rough demonstration):
Thread thread=new Thread("name") {
public void run()
{
// do stuff
}
}.start();
the second is:
making a class that imlpements runnable,
creating a thread :
Thread thread = new Thread(this,"name").start();
and the third (in android, i don't if it can work some how else):
making a Handler,
creating a Runnable,
and having handler.postDelayed(runnable), or handler.post(runnable).
I don't understand what's the difference, the only thing i did notice is that making a Thread makes the run loop work a lot faster than using a handler.
could some one explain to me what's the difference between them and what should i use to what?
The first and the second way are exactly the same. It is just different constructions that can be more useful in different situations. Note that Thread implements Runnable and may just run himself in the new thread.
The third way is a little bit misinterpreted by you. Handler runs Runnable in the thread where the Handler was instantiated (unless you specify another looper). If you created your Handler in the UI thread it will run Runnable in the UI thread as well. And as a result it may work slower.
Related
The following code leads to java.lang.IllegalThreadStateException: Thread already started when I called start() method second time in program.
updateUI.join();
if (!updateUI.isAlive())
updateUI.start();
This happens the second time updateUI.start() is called. I've stepped through it multiple times and the thread is called and completly runs to completion before hitting updateUI.start().
Calling updateUI.run() avoids the error but causes the thread to run in the UI thread (the calling thread, as mentioned in other posts on SO), which is not what I want.
Can a Thread be started only once? If so than what do I do if I want to run the thread again? This particular thread is doing some calculation in the background, if I don't do it in the thread than it's done in the UI thread and the user has an unreasonably long wait.
From the Java API Specification for the Thread.start method:
It is never legal to start a thread
more than once. In particular, a
thread may not be restarted once it
has completed execution.
Furthermore:
Throws:
IllegalThreadStateException - if the thread was already started.
So yes, a Thread can only be started once.
If so than what do I do if I want to
run the thread again?
If a Thread needs to be run more than once, then one should make an new instance of the Thread and call start on it.
Exactly right. From the documentation:
It is never legal to start a thread
more than once. In particular, a
thread may not be restarted once it
has completed execution.
In terms of what you can do for repeated computation, it seems as if you could use SwingUtilities invokeLater method. You are already experimenting with calling run() directly, meaning you're already thinking about using a Runnable rather than a raw Thread. Try using the invokeLater method on just the Runnable task and see if that fits your mental pattern a little better.
Here is the example from the documentation:
Runnable doHelloWorld = new Runnable() {
public void run() {
// Put your UI update computations in here.
// BTW - remember to restrict Swing calls to the AWT Event thread.
System.out.println("Hello World on " + Thread.currentThread());
}
};
SwingUtilities.invokeLater(doHelloWorld);
System.out.println("This might well be displayed before the other message.");
If you replace that println call with your computation, it might just be exactly what you need.
EDIT: following up on the comment, I hadn't noticed the Android tag in the original post. The equivalent to invokeLater in the Android work is Handler.post(Runnable). From its javadoc:
/**
* Causes the Runnable r to be added to the message queue.
* The runnable will be run on the thread to which this handler is
* attached.
*
* #param r The Runnable that will be executed.
*
* #return Returns true if the Runnable was successfully placed in to the
* message queue. Returns false on failure, usually because the
* looper processing the message queue is exiting.
*/
So, in the Android world, you can use the same example as above, replacing the Swingutilities.invokeLater with the appropriate post to a Handler.
No, we cannot start Thread again, doing so will throw runtimeException java.lang.IllegalThreadStateException.
>
The reason is once run() method is executed by Thread, it goes into dead state.
Let’s take an example-
Thinking of starting thread again and calling start() method on it (which internally is going to call run() method) for us is some what like asking dead man to wake up and run. As, after completing his life person goes to dead state.
public class MyClass implements Runnable{
#Override
public void run() {
System.out.println("in run() method, method completed.");
}
public static void main(String[] args) {
MyClass obj=new MyClass();
Thread thread1=new Thread(obj,"Thread-1");
thread1.start();
thread1.start(); //will throw java.lang.IllegalThreadStateException at runtime
}
}
/*OUTPUT in run() method, method completed. Exception in thread
"main" java.lang.IllegalThreadStateException
at java.lang.Thread.start(Unknown Source)
*/
check this
The just-arrived answer covers why you shouldn't do what you're doing. Here are some options for solving your actual problem.
This particular thread is doing some
calculation in the background, if I
don't do it in the thread than it's
done in the UI thread and the user has
an unreasonably long wait.
Dump your own thread and use AsyncTask.
Or create a fresh thread when you need it.
Or set up your thread to operate off of a work queue (e.g., LinkedBlockingQueue) rather than restarting the thread.
What you should do is create a Runnable and wrap it with a new Thread each time you want to run the Runnable.
It would be really ugly to do but you can Wrap a thread with another thread to run the code for it again but only do this is you really have to.
It is as you said, a thread cannot be started more than once.
Straight from the horse's mouth: Java API Spec
It is never legal to start a thread
more than once. In particular, a
thread may not be restarted once it
has completed execution.
If you need to re-run whatever is going on in your thread, you will have to create a new thread and run that.
To re-use a thread is illegal action in Java API.
However, you could wrap it into a runnable implement and re-run that instance again.
Yes we can't start already running thread.
It will throw IllegalThreadStateException at runtime - if the thread was already started.
What if you really need to Start thread:
Option 1 ) If a Thread needs to be run more than once, then one should make an new instance of the Thread and call start on it.
Can a Thread be started only once?
Yes. You can start it exactly once.
If so than what do I do if I want to run the thread again?This particular thread is doing some calculation in the background, if I don't do it in the thread than it's done in the UI thread and the user has an unreasonably long wait.
Don't run the Thread again. Instead create Runnable and post it on Handler of HandlerThread. You can submit multiple Runnable objects. If want to send data back to UI Thread, with-in your Runnable run() method, post a Message on Handler of UI Thread and process handleMessage
Refer to this post for example code:
Android: Toast in a thread
It would be really ugly to do but you can Wrap a thread with another thread to run the code for it again but only do this is you really have to.
I have had to fix a resource leak that was caused by a programmer who created a Thread but instead of start()ing it, he called the run()-method directly. So avoid it, unless you really really know what side effects it causes.
I don't know if it is good practice but when I let run() be called inside the run() method it throws no error and actually does exactly what I wanted.
I know it is not starting a thread again, but maybe this comes in handy for you.
public void run() {
LifeCycleComponent lifeCycleComponent = new LifeCycleComponent();
try {
NetworkState firstState = lifeCycleComponent.getCurrentNetworkState();
Thread.sleep(5000);
if (firstState != lifeCycleComponent.getCurrentNetworkState()) {
System.out.println("{There was a NetworkState change!}");
run();
} else {
run();
}
} catch (SocketException | InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
Thread checkingNetworkStates = new Thread(new LifeCycleComponent());
checkingNetworkStates.start();
}
Hope this helps, even if it is just a little.
Cheers
Usually to start a thread we either extend the Thread class or implements Runnable interface and override run() method. But in the code below we are not doing any of above and in fact it is using anonymous class to create a thread. Is it really a good/legal/advisable way to start a thread in java?
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
}
});
thread.start();
Is it really a good/legal/advisable way to start a thread in java?
good? -
whether its good depends on your requirements, if you need a thread to run some heavy function in a kind of fire and forget manner then it might be fine.
legal? - it is legal - this code compiles and runs just fine
advisable? - not really, this is probably opinion-based but I would advise to use Executors together with Future and FutureTask
There are two reasons why I'd do this
Learning how to use anonymous threads
When I have a thread that has predictable behavior and I can guarantee completion within the thread.
I'd avoid this structure otherwise.
It is a bad way to do it because you need to copy/paste the run method for each Thread.
It is the same reason of why using method/class instead of put all code in one file.
buddy it totally depends on your requirement, there might be use cases where you need to access the private variables of the outer class hence you used inner anonymous class. And about the spawning new threads, say you are using it for a specific purpose say Network calls in that case you should use it properly where you design a thread pool and use a spawn a limited number of thread irrespective of number of network requests.
I have a Thread which runs my game loop. I want to be able to run this game loop each time I start a new game. But since the threads in Java can only be started once, how can I do this?
Create a new Thread around the same Runnable instance and start that.
Since you want the Thread that runs the game loop to keep running it, you need to code it something like this:
public class GameLoop implements Runnable {
...
public void run() {
while (gameNotFinished) {
// do stuff
}
}
}
If that is not working, then the chances are that the run() method is dying because of an exception that you are not catching / logging, and therefore not noticing.
1. When you say that "you need to run a thread", i means you want to start a sub-task on a separate thread.
2. Now if you mean this certain sub-task, then please prefer to run a new thread.
3. As you said But since the threads in Java can only be started once
This means that when a thread (thread of execution) completes its run() method, then the Thread object associated with it permanently looses its threadness, right....
But if this thread is from a pool, then the pool itself manages the Thread objects and its reused. Try using Executors from java.util.concurrent package.
1) The short answer is precisely what SLaks already said: just "...create a new thread around the same runnable instance and start that."
2) I think you might be confused about the distinction between the everyday meaning of "start", and the semantics of the Java Thread method "start()". This tutorial might help:
http://www.geom.uiuc.edu/~daeron/docs/javaguide/java/threads/states.html
3) Should you wish to re-use the same thread, you can use the methods "wait()" and "resume()":
http://www.javabeginner.com/learn-java/java-threads-tutorial
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Java: “implements Runnable” vs. “extends Thread”
I'm just wondering is there some subtle difference between creating your own custom object that extends Thread and creating a thread using the Thread(Runnable) constructor?
I have some code that works fine when I use classes that extend Thread, but if I try to use logic that creates Threads by using the Thread(Runnable) constructor the new threads do not seem to work properly - I can't detect that they are alive in the same way as when I use the custom sub-classes I made and they do not seem to end, ever.
In my code I'm just spawning a few threads then searching through my list of threads to find one that is alive and joining with it until it dies. Then I once again search for a thread in the list that is alive and join to it.. this continues until all threads die.
Thanks for reading.
A Thread is a resource for doing work. A Runnable is a piece of work. Are you creating a new type of resource, or just defining the work you want done?
To 'end' the thread you simply return from the 'run' method. Would need to see an example of your code to see what you mean about not being able to tell if they're active.
Creating Runnables also of course makes it easier to refactor your code to use a ThreadPool in the future.
In my code I'm just spawning a few threads then searching through my list of threads to find one that is alive and joining with it until it dies.
How (and why) are you "searching through my list of threads"? I would instead add the Thread to some sort of Collection that you then can then iterate across and join with each Thread in turn:
List<Thread> threads = new ArrayList<Thread();
for (int i = 0; i < 100; i++) {
Thread thread = new Thread(new Runnable() ...);
thread.start();
threads.add(thread);
}
...
for (Thread thread : threads) {
thread.join();
}
Even better would be to use one of the ExecutorServices given by Executors. They have a lot of features around creating thread-pools and waiting for the pool to completely finish. Almost always recommended over new Thread(...).
I can't detect that they are alive in the same way as when I use the custom sub-classes I made
If you are trying to set the name of the Thread then you can't do this in the constructor of your Runnable. You can however do this in the run() method. You can do:
new Thread(new Runnable() {
public void run() {
Thread.currentThread().setName("...");
}
});
Otherwise, I'm not sure why you wouldn't be seeing your Thread unless it has already finished.
they do not seem to end, ever.
Using a Runnable, the thread finishes when the run() method returns -- either through a return or a throw. This is very much the same as extending Thread so I'm not sure why this wouldn't work.
I would really recommend to use the concurrency utility and not trying to manage yourself the Threads, which is complicated and error prone.
Using the concurrent api will also help you to apply the right patterns straight away.
I would like to know what are the differences between each of the following implementations for threads, and when should I use each option.
1- Implementing Runnable
public class ClientThread implements Runnable
{
new Thread(this).start();
public void run()
{...}
}
2- Extending Thread
class ServerThread extends Thread
{
this.start();
public void run()
{...}
}
3- Worker Threads and SwingWorker which I'm really not familiar with...
Thank you very much
Hi I've added another question in this matter below, it was published as an answer cause
I accidentally erased my cookies in the web browser thanks..
Okay guys thanks for all the info..
But, what should I use if I want to implement a count down timer for swing game which will run on screen parallel to the game without blocking the flow of the game because of the consistent timer in the background which will be shown there and probably will need to be run on the event dispatch thread...
Can I use the Runnable implementation or I must use swing worker?
This is the preferred way, since it separates the concerns of providing the code the thread should run (the job of the Runnable instance) and the job of managing the thread (the Thread instance), and also allows to have the Runnable be a subclass of something else
Less clean, but works just as well
"Worker Thread" is a conceptual name for threads that run parallel to the main application. SwingWorker is a class designed to implement a worker tread in a Swing application. It offers an API for the worker thread to communicate its status to the Swing event thread so that it can e.g. update a progress bar.
Note that it's generally very hard to work with threads manually. If you need multiple threads for performance reasons, it's much better to work with a thread pool via the Executors class.
In general, it's preferred to implement Runnable rather than extend thread. There are a few reasons for this. First of all, since Java doesn't support multiple inheritance, sometimes extending Thread isn't an option. Also, from an OOP perspective, it usually makes more sense to implement Runnable instead; you're not adding functionality to the Thread class, you're creating something to be run.
However, if you actually are adding functionality to Thread (in which case you will probably need to make lots of these Thread subclasses), then just extend Thread.
The official Java lesson on concurrency covers this very topic.
Defining and Starting a Thread
Which of these idioms should you use?
The first idiom, which employs a Runnable object, is more general, because the Runnable object can subclass a class other than Thread.
The second idiom is easier to use in simple applications, but is limited by the fact that your task class must be a descendant of Thread.
A very near duplicate from "implements Runnable" vs. "extends Thread" except the third point which I'm really not familiar with either. I would recommend reading that post as it contains a lot of very good info.
When you just want to run it in a separate thread. // The normal case
When extending the thread class functions or behavior.
Somebody else fill in :)
Almost all of the time you should use #1 due to it's semantics. You use it as a runnable you do not generally extend the thread class functions.
You should not use SwingWorker unless you are using swing.
Implementing Runnable (option 1) is generally preferable to extending Thread.