File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Threads and Synchronization and the fly likes how to maintain single instance of a thread? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of OCM Java EE 6 Enterprise Architect Exam Guide this week in the OCMJEA forum!
JavaRanch » Java Forums » Java » Threads and Synchronization
Bookmark "how to maintain single instance of a thread?" Watch "how to maintain single instance of a thread?" New topic
Author

how to maintain single instance of a thread?

Ankit Yadav
Greenhorn

Joined: Jul 07, 2009
Posts: 12
i used this logic so far:

but someone said,
it is prone to race condition as the thread may eventually be dead, just after checking isAlive() and isAlive() should almost always be used for diagnostic purposes, not for logic to start another thread..

is that true & critical to handle?

in my opinion, it shouldn't be an issue, because even if thread immediately stops, it shouldn't be a problem, as thread did exist at point of check. that means process we want to start is already 'started' or 'still going on'. no matter how much time it takes to die after check or thread.start(), 1ms or 1s.

correct me if wrong.
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18765
    
  40

Ankit Yadav wrote:i used this logic so far:

but someone said,
it is prone to race condition as the thread may eventually be dead, just after checking isAlive() and isAlive() should almost always be used for diagnostic purposes, not for logic to start another thread..

is that true & critical to handle?

in my opinion, it shouldn't be an issue, because even if thread immediately stops, it shouldn't be a problem, as thread did exist at point of check. that means process we want to start is already 'started' or 'still going on'. no matter how much time it takes to die after check or thread.start(), 1ms or 1s.

correct me if wrong.



First, what do you mean by "immediately stops"? Threads don't do that -- or are you referring to thread starvation?

Anyway, the alive flag is set to true sometime after the invocation of the start() method. And is set to false sometime during the thread clean up code -- which is after the application specific logic has already terminated.

So, is this a race condition? That depends on what your application requires. If your application requires that the application logic of that thread is still running, then it is a race condition. If your application only cares that the logic was executed recently, and *not* to guarantee the thread is up and able to handle a follow up call, then it is not a race condition. It really depends on what you need the other thread for.

Henry

Books: Java Threads, 3rd Edition, Jini in a Nutshell, and Java Gems (contributor)
Jayesh A Lalwani
Bartender

Joined: Jan 17, 2008
Posts: 2343
    
  28

If you are starting a thread just to kick off another background task after the currently executing background task is done, I wouldn't do what you are doing. Not because of race condition, but because thread is a costly thing to start. It's better to have the thread sleep after it's done with a task, and it wakes up after you give it the next task.

A thread is like a friendly dragon. Don't slay your friendly dragon. Let it sleep.
Ankit Yadav
Greenhorn

Joined: Jul 07, 2009
Posts: 12
Henry Wong wrote:
First, what do you mean by "immediately stops"? Threads don't do that -- or are you referring to thread starvation?

Anyway, the alive flag is set to true sometime after the invocation of the start() method. And is set to false sometime during the thread clean up code -- which is after the application specific logic has already terminated.

So, is this a race condition? That depends on what your application requires. If your application requires that the application logic of that thread is still running, then it is a race condition. If your application only cares that the logic was executed recently, and *not* to guarantee the thread is up and able to handle a follow up call, then it is not a race condition. It really depends on what you need the other thread for.

Henry

the race condition when immediately after checking (thread.isAlive()) and before executing the next statement, thread dies
(which actually seem illogical to me, but as author of a well known book posted so on a forum, i thought of clarifying it)
my que is, is it logical to treat this as a real condition rather than hypothetical one?

moreover, i could not understand your last statement. my singleton thread is used as ever running service. to optimize it a bit (to use in mobile device) i made a logic that, as long as data is coming, same thread is kept running, but if data is not available for sometime, instead of sleep() i let the thread to terminate, and as soon as data is available, i check if thread is alive, no need to create new thread, as the existing one, will already process the queued data. but if thread is terminated, we need to create n start thread.

here my que is, can there be ever any race condition?

Jayesh A Lalwani wrote:
If you are starting a thread just to kick off another background task after the currently executing background task is done, I wouldn't do what you are doing. Not because of race condition, but because thread is a costly thing to start. It's better to have the thread sleep after it's done with a task, and it wakes up after you give it the next task.

you gave a good point, but ain't it will also waste resources in repeatedly waking up and checking whether data is available? i specifically used this logic in mobile devices, to avoid a continues thread that will ultimately drain the battery. does that make sense considering the use-case i mentioned above? is that a wrong approach?
Jayesh A Lalwani
Bartender

Joined: Jan 17, 2008
Posts: 2343
    
  28

Hmm not sure about the battery, but I suspect a blocked thread won't use up any resources. I could be wrong.
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18765
    
  40

Ankit Yadav wrote:
moreover, i could not understand your last statement. my singleton thread is used as ever running service. to optimize it a bit (to use in mobile device) i made a logic that, as long as data is coming, same thread is kept running, but if data is not available for sometime, instead of sleep() i let the thread to terminate, and as soon as data is available, i check if thread is alive, no need to create new thread, as the existing one, will already process the queued data. but if thread is terminated, we need to create n start thread.

here my que is, can there be ever any race condition?


Given this scenario, you definitely have a race condition. Imagine this, data stops arriving for a short period -- and during this period, your service thread detects it should exit and starts the process of terminating. Around the same time, new data arrives. This triggers a check to see if the thread is still alive, which it is... because it just detected that it should terminate. Your service thread still has to clean up resources, and the java library (and OS has a lot of work to do too, to tear down the thread). And during all of this, the thread is considered alive. After all, it hasn't finish terminating yet, so it is alive.

The service thread is still alive. And it may still be alive a period measured in milliseconds while it terminates. Yes, there is data in the queue, but the service thread doesn't know that -- it decided to terminate before the data arrived.

Now, the question is, is this race condition important? So what that there is queued data and the service thread is just exiting? Some time in the future, the service thread will finish terminating, it will then be marked as not alive, and when more data arrives, a new service thread will be started, which will process all the data in the queue. If this is acceptable for your application, then the race condition should be fine.

Henry
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18765
    
  40

Ankit Yadav wrote:
the race condition when immediately after checking (thread.isAlive()) and before executing the next statement, thread dies
(which actually seem illogical to me, but as author of a well known book posted so on a forum, i thought of clarifying it)
my que is, is it logical to treat this as a real condition rather than hypothetical one?


The race condition is not between "immediately after checking (thread.isAlive()) and before executing the next statement". The race condition is between the service thread determining that the thread should terminate, and the huge amount of code that the thread, the java library, and the OS has to do to actually terminate that thread.

The service thread may be still be alive at the next statement. The service thread may still be alive after the next 1000 statements. Heck, the service thread may still be considered alive for the next few calls as more data is still coming in.... but is the service thread useful? It is terminating. It is no longer checking the queue or processing. It is terminating.

Henry
Ankit Yadav
Greenhorn

Joined: Jul 07, 2009
Posts: 12
Henry Wong wrote:
Ankit Yadav wrote:
the race condition when immediately after checking (thread.isAlive()) and before executing the next statement, thread dies
(which actually seem illogical to me, but as author of a well known book posted so on a forum, i thought of clarifying it)
my que is, is it logical to treat this as a real condition rather than hypothetical one?


The race condition is not between "immediately after checking (thread.isAlive()) and before executing the next statement". The race condition is between the service thread determining that the thread should terminate, and the huge amount of code that the thread, the java library, and the OS has to do to actually terminate that thread.

The service thread may be still be alive at the next statement. The service thread may still be alive after the next 1000 statements. Heck, the service thread may still be considered alive for the next few calls as more data is still coming in.... but is the service thread useful? It is terminating. It is no longer checking the queue or processing. It is terminating.

Henry


ok, so all i could get is, as such it would not be a problem, but if app is suppose to process data as soon as its available, there it might leave data unprocessed for much longer duration.

so what would you suggest alternately as a better solution?
letting the thread go to sleep() and wake up in intervals to check the availability of data? then how should we optimize the the sleep() period? or is there any other solution?

1 solution what i could think is, not sure how good it is, rather than depending upon isAlive, keep an additional boolean variable to track thread execution, and set it in the last statement in run(), so that it will be more a replica of thread-execution rather excluding time spent in alive-but-terminating state.
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18765
    
  40

Ankit Yadav wrote:
ok, so all i could get is, as such it would not be a problem, but if app is suppose to process data as soon as its available, there it might leave data unprocessed for much longer duration.


Correct. Remember that a race condition just means that there a series of possible outcomes -- and if all possible outcomes are acceptable, then the race condition is not an issue. It is only an issue if you have a requirement that can't accept one of the outcomes -- regardless of how unlikely it may occur.

Ankit Yadav wrote:
so what would you suggest alternately as a better solution?
letting the thread go to sleep() and wake up in intervals to check the availability of data? then how should we optimize the the sleep() period? or is there any other solution?


Did you know that threads existed before Java existed? And did you know that Java is approaching 2 decades? And during all this time, don't you think the "optimize the sleep() period" problem has been solved? ...

There are multiple way to do it.... The standard way, if you are concerned about improving the sleep() functionality, is to use wait/notify. With this mechanism, the service thread waits exactly til it is notified that data has arrived -- no more or less. It is placed in a sleeping state for exactly the amount of time til there is data.

As a side note, there are race conditions around missing notifications -- which requires that wait/notify be tightly integrated with the threading system. Unfortunately, newbies don't realize this, and generally, wind up being confused with why wait/notify need to own the synchronization lock (when sleep doesn't), and then just wrapping a synchronized block around the code (not taking care of missing possible notifications)... but I digress.


Another way to do this, since you are already using a queue, is to use a blocking queue. With the blocking queue, the request thread (producer) simply adds data to the queue, and the service thread (consumer) simply takes data from the queue, and the blocking queue makes sure that the consumer waits for the exact amount if no data is available. And optionally, if there is a fix size to the queue, makes sure that the producer waits for the exact amount until there is room on the queue. And more importantly, the blocking queue takes care of all the race conditions of missing notifications (so even a beginner can get interthread communications correct).

Henry
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: how to maintain single instance of a thread?