IllegalThreadStateException: Thread already started on a new Thread - java

i have an Android App published in the Play Store, and the crashreports show a Fatal Exception: java.lang.IllegalThreadStateException: Thread already started
in
public void refresh(){
if (Thread.currentThread() != mThread) {
mThread = new Thread() {
#Override
public void run() {
refresh();
}
};
mThread.start();//<<<<<<<<<<<<<here
return;
}
doSomeCoolStuff();
}
how can this happen? it is a new thread?
Metin Kale

This can happen in case of a race condition. Between the two statements (assigning a value to mThread and calling the start() method), the execution can switch to another thread, which can enter the refresh() method again, assign a different thread to mThread, and then start it. When the first thread resumes execution, mThread will contain a different thread (which has already been started), and the start() method will fail with the exception that you describe.
One way to fix this is to store the result of new Thread() in a local variable, then call the start() method on that variable, and then save it into the field. (This may not be the most appropriate fix, but it's not possible to say more without knowing more details about the context where the problem happens.)

Probably your mThread is already started and running, thats why do you get that exception.
Try to check the state of mThread, and start it only when is in Thread.State.NEW state.
if (mThread.getState() == Thread.State.NEW)
{
mThread.start();
}
Thread.State.NEW: The thread has been created, but has never been started.

Related

How do I correctly create another thread instance from the same Runnable?

I have a class called Flash that has a Runnable defined in it.
class Flash
{
Runnable slow = new Runnable(){
public void run(){
//Do stuff here
}
}
};
Thread slowThread = null; //Just declared a Thread variable
//more stuff here
}
Now I have a method named blinkslow() that creates a new thread class object using the slow runnable:
void blinkSlow()
{
if(!threadRunning) //Boolean to make sure the thread is not running(works fine)
{
slowThread=null;
slowThread = new Thread(slow);
slowThread.start();
threadRunning = true;
}
}
Now, when the run() method finishes its job, in its last statement, it sets this boolean flag threadRunning to false, and exits.
Then when I call the method blinkslow() the second time, the thread does not run. Why is this happening?
I've made sure that:
The thread has stopped i.e. completes its run() method before calling the blinkshow() method again.
I'm not trying to re-start the same thread again, as the statement slowThread = new Thread(slow); creates a new instance of the Thread class with my Runnable each time its called.
How can I create another instance of the runnable again after it has ended its execution for the first time? What I've done above isn't working for the second time, and I have no clue why.
I just figured out what I was doing wrong, and I feel silly right now. I had another flag stop (a boolean variable) inside the run method. I forgot to unset it after first run.
The above code will run fine without any problem, unless you were me.
When a thread is finshed, he enters the "dead" state, and it cannot be used anymore.
To use the run method, you need to create à new instance of the thread object.

How to stop/interrupt running thread from another method?

I am a total beginner to android and Java development, and I am currently trying to make a metronome.
The first problem I encountered after getting the sound playback to work, is that whenever the metronome played the app would stop responding - that's when I learned about threads and how I should use a new thread for my audio playback.
Creating a new thread helped and now the app runs fine, but I can't get the thread to stop/interrupt. I've read maybe 50 articles already about threads and interrupts and I can't figure it out.
Here is my 'Player' class code, which I've mostly copied from another Stack Overflow post (I have tried countless other ways and variations and none worked):
package com.example.t.firstapp;
import android.util.Log;
public class Player implements Runnable {
Thread backgroundThread;
Metronome m;
public void start() {
if (backgroundThread == null) {
backgroundThread = new Thread(this);
m = new Metronome();
backgroundThread.start();
}
}
public void stop() {
if (backgroundThread != null) {
backgroundThread.interrupt();
}
}
public void run() {
try {
Log.i("a", "Thread starting.");
while (!backgroundThread.isInterrupted()) {
m.play();
}
Log.i("b", "Thread stopping.");
throw new InterruptedException(); // ???
} catch (InterruptedException ex) {
// important you respond to the InterruptedException and stop processing
// when its thrown! Notice this is outside the while loop.
Log.i("c", "Thread shutting down as it was requested to stop.");
} finally {
backgroundThread = null;
}
}
}
Note the line marked with "???". I added that one myself because otherwise the "catch (InterruptedException ex)" returned an error.
Here is the relevant code from my MainActivity class:
public class MainActivity extends AppCompatActivity {
...
public Player p;
...
public void play() {
p = new Player();
p.start();
}
public void stop() {
p.stop();
}
}
Calling p.stop(); from within the method 'stop' doesn't actually do anything. This is where I get stuck. If I call p.stop() immediately after I start the thread, like this:
public void play() {
p = new Player();
p.start();
p.stop();
}
Then it works, and I see all of the relevant log messages from the Player class. Why doesn't p.stop() work when I call it from my 'stop' method? Is it because I am calling it from a different method, or is it because I am not calling it immediately?
Any help would be greatly appreciated since this is extremely frustrating. I have been studying and practicing Android development for only a week now, but I haven't done anything over the last 5 days but try to solve this problem. Thanks
You misunderstood the concept of interruption. Interupting is not some magical way of forcing the thread to stop, rather it will only work for methods that have interruption support - like sleeping.
Take a look at the Thread#interrupt() API, where it lists interrupt supported methods:
If this thread is blocked in an invocation of the wait(), wait(long), or wait(long, int) methods of the Object class, or of the join(), join(long), join(long, int), sleep(long), or sleep(long, int), methods of this class, then its interrupt status will be cleared and it will receive an InterruptedException.
If this thread is blocked in an I/O operation upon an interruptible channel then the channel will be closed, the thread's interrupt status will be set, and the thread will receive a ClosedByInterruptException.
If this thread is blocked in a Selector then the thread's interrupt status will be set and it will return immediately from the selection operation, possibly with a non-zero value, just as if the selector's wakeup method were invoked.
If none of the previous conditions hold then this thread's interrupt status will be set.
You can nicely implement your own methods with interrupt support, by contantly checking for the interrupt status.
Now let's see how we can solve your problem.
According to your comment, m.play() does not return, meaning, once m.play() is called, the while never checks if the thread has been interrupted; in turn it will never stop, since m.play() isn't implemented to support interrupts. This should also explain why the compiler complains that nobody throws an InterruptedException. (The reason it worked if interrupted immediately, is that the interrupt status is changed before it reaches the while... Think of it.)
Now, I assume that, if you will call m.stop(), m.play() will return, successfully rechecking for thread interruption. That's why it worked, as mentioned in comment.
But look, there's no real use of interrupting the thread - since all you have to do is call m.stop() and release the m.play(), just play and wait to return - which means stop has been called. Same to the while loop, drop it all the way.
public void run() {
Log.i("a", "Thread starting.");
m.play(); // blocks till stopped from some other thread...
Log.i("b", "Thread stopping.");
Log.i("c", "Thread shutting down as it was requested to stop.");
backgroundThread = null;
}
One case where I may see a use of the while and interrupt, if m.play() may return earlier than by calling m.stop() (say, by some exception), and you want to restart the metronome until stop is called; then a loop may be on the rescue, and interrupt may signal that it was actually stopped by calling m.stop().
public void run() {
Log.i("a", "Thread starting.");
while (!backgroundThread.isInterrupted()) {
m.play();
if(!backgroundThread.isInterrupted())
Log.i("b", "Stopped by exception, restarting....");
}
Log.i("c", "Thread stopping.");
Log.i("d", "Thread shutting down as it was requested to stop.");
backgroundThread = null;
}

Singleton with Java multithreading app

Briefly, I want to click on a button to run a background task (separated thread). I faced two problems:
What if user click many times on that button ==>Many thread will be
created.
Even if I use Singleton mechanism, I face another problem which is the fact that only one time that instance will be created even though after task accomplishes, user can't anymore re-run the process (second click on the button).
My class:
package mypack.check;
public class RunnableCheck implements Runnable {
private Thread t;
private static RunnableCheckFeeders instance;
public RunnableCheckFeeders getDefault() {
if (instance == null) {
instance = new RunnableCheckFeeders();
}
return instance;
}
#Override
public void run() {
//What the thread is supposed to do...
}
public void start() {
if (t == null) {
t = new Thread(this, "My task");
t.start();
}
}
}
In the caller class:
RunnableCheckFeeders.getDefault().start();
I tried with Synchronized methods but in vain, any proposition is welcome.
I suggest you use an ExecutorService.
enum RunOne {; // no instances
static final ExecutorService service = Executors.newSingleThreadedExecutor();
static Future last = null;
static synchronized void run(Runnable run) {
if (last != null && !last.isDone()) return;
last = service.submit(run);
}
}
This will submit a new task only if there is not already one running. It won't create more than one thread but you can submit tasks after a previous one finishes. You can call service.shutdown() to stop the service.
Your start method doesn't guarantee that only one "my task" thread will be created, even if there is only one instance of RunnableCheck: because the checking of the thread reference and subsequent assignment is not atomic, it is possible for two threads to be created and started if both happen to evaluate t == null to true at the same time (or, at least, a second thread can evaluate it to true before the first thread was able to assign a non-null value to t).
You can guard for this by:
Making the start method synchronized, so multiple threads cannot run the method at the same time;
Add an AtomicBoolean to record if the thread has been created/started. By updating the value of this flag atomically, it is not possible for two threads to set it to true, and thus impossible for two new Threads to be created and started:
private final AtomicBoolean started = new AtomicBoolean();
private Thread t;
public void start() {
if (!started.compareAndSet(false, true)) {
return;
}
t = new Thread(this, "My task");
t.start();
}
When a user clicks multiple times then do you want the event to happen multiple times, or just the once? If multiple times, you don't want a singleton, but rather to create a queue of work.
You can do this in one of two ways, the first is to use a a want a thread pool, likely using one from the ExecutorService.
Your second option is to have a single queue reading from a queue and a single thread reading from the queue.
If you want the event to only happen the once then you need to disable the button until it is completed, make start synchronized so only one thread can call it at a time and then set t to null once the thread finishes (i.e. the last item in run()).

Proper way to end an instance of a class?

In my Android app, I have a class that extends Thread that runs when there's an established internet connection (3G/WIFI).
When the app is loaded, if an internet connection is established, I instantiate the class like this:
MyThread thread = new MyThread(); // (it calls its own start() method)
In the thread, if the connection is lost, I want to destroy the Thread. I was told not to run finalize(), how would I destroy it so that thread == null is true?
Edit: The reason I was asking was, later on, I would like to restart the thread in case connectivity returned, and a check to see if (thread == null) would have been easy. I could just use a flag to indicate the thread needs to be restarted or check to see if it was interrupted. Thanks for the helpful comments so far.
Generally, you don't subclass Thread. You create a Runnable, and pass it into a Thread object, or better yet, an ExecutorService.
But you don't have to worry about cleaning up after the thread is done, it will be handled automatically by the garbage collector. If you want your own local reference to be null, just null it out yourself, or better yet, don't hang on to it.
new Thread( new Runnable() {
public void run() {
// put your stuff here
}
} ).start();
Try this,
A thread of execution will live until it has finished executing its run() method, then
it either moves to the dead state or in the thread pool.
Its always better to control the run() method using aboolean variable.
eg:
boolean isRunning = true;
new Thread(new Runnable()
{
public void run()
{
while(isRunning)
{
// Keep doing your work here....
if (!isRunning){
break;
}
}
}
}).start();

How to stop a java thread gracefully?

I wrote a thread, it is taking too much time to execute and it seems it is not completely done. I want to stop the thread gracefully. Any help ?
The good way to do it is to have the run() of the Thread guarded by a boolean variable and set it to true from the outside when you want to stop it, something like:
class MyThread extends Thread
{
volatile boolean finished = false;
public void stopMe()
{
finished = true;
}
public void run()
{
while (!finished)
{
//do dirty work
}
}
}
Once upon a time a stop() method existed but as the documentation states
This method is inherently unsafe. Stopping a thread with Thread.stop causes it to unlock all of the monitors that it has locked (as a natural consequence of the unchecked ThreadDeath exception propagating up the stack). If any of the objects previously protected by these monitors were in an inconsistent state, the damaged objects become visible to other threads, potentially resulting in arbitrary behavior.
That's why you should have a guard..
The bad part about using a flag to stop your thread is that if the thread is waiting or sleeping then you have to wait for it to finish waiting/sleeping. If you call the interrupt method on the thread then that will cause the wait or sleep call to be exited with an InterruptedException.
(A second bad part about the flag approach is that most nontrivial code is going to be utilizing libraries like java.util.concurrent, where the classes are specifically designed to use interruption to cancel. Trying to use the hand rolled flag in a task passed into an Executor is going to be awkward.)
Calling interrupt() also sets an interrupted property that you can use as a flag to check whether to quit (in the event that the thread is not waiting or sleeping).
You can write the thread's run method so that the InterruptedException is caught outside whatever looping logic the thread is doing, or you can catch the exception within the loop and close to the call throwing the exception, setting the interrupt flag inside the catch block for the InterruptedException so that the thread doesn't lose track of the fact that it was interrupted. The interrupted thread can still keep control and finish processing on its own terms.
Say I want to write a worker thread that does work in increments, where there's a sleep in the middle for some reason, and I don't want quitting the sleep to make processing quit without doing the remaining work for that increment, I only want it to quit if it is in-between increments:
class MyThread extends Thread
{
public void run()
{
while (!Thread.currentThread().isInterrupted())
{
doFirstPartOfIncrement();
try {
Thread.sleep(10000L);
} catch (InterruptedException e) {
// restore interrupt flag
Thread.currentThread().interrupt();
}
doSecondPartOfIncrement();
}
}
}
Here is an answer to a similar question, including example code.
You should not kill Thread from other one. It's considered as fairly bad habit. However, there are many ways. You can use return statement from thread's run method.
Or you can check if thread has already been interrupted and then it will cancel it's work. F.e. :
while (!isInterrupted()) {
// doStuff
}
Make a volatile boolean stop somewhere. Then in the code that runs in the thread, regularly do
if (stop) // end gracefully by breaking out of loop or whatever
To stop the thread, set stop to true.
I think you must do it manually this way. After all, only the code running in the thread has any idea what is and isn't graceful.
You need to send a stop-message to the Thread and the Thread itself needs to take action if the message has been received. This is pretty easy, if the long-running action is inside loop:
public class StoppableThread extends Thread {
private volatile boolean stop = false;
public void stopGracefully() {
stop = true;
}
public void run() {
boolean finished = false;
while (!stop && !finished) {
// long running action - finished will be true once work is done
}
}
}
For a thread to stop itself, no one seems to have mentioned (mis)using exception:
abstract class SelfStoppingThread extends Thread {
#Override
public final void run() {
try {
doRun();
} catch (final Stop stop) {
//optional logging
}
}
abstract void doRun();
protected final void stopSelf() {
throw new Stop();
}
private static final class Stop extends RuntimeException {};
}
A subclass just need to override doRun() normally as you would with a Thread, and call stopSelf() whenever it feels like it wants to stop. IMO it feels cleaner than using a flag in a while loop.

Categories