I found a piece of code where the thread seems to starve. Below is a simplified example. Is this an example for starvation? What is the reason why the thread does not terminate?
Note: Changing the sleep to 1 will sometimes result in termination. The commented out Thread.yield() would solve the problem (for me).
public class Foo {
public static boolean finished = false;
public static void main(String[] args) {
Runnable worker = new Runnable() {
#Override
public void run() {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finished = true;
}
};
new Thread(worker).start();
while (!finished) {
// Thread.yield();
}
}
}
You probably need to get informed on the Java Memory Model. Multithreading isn't just about interleaving the actions of threads; it is about the visibility of actions by one thread to another.
At the bottom of this issue lies the need for aggressive optimization in the face of concurrency: any mechanism which ensures memory coherency between threads is expensive, and much (most) of the data is not shared between threads. Therefore the data not explicitly marked volatile, or protected by locks, is treated as thread-local by default (without strict guarantees, of course).
In your case, finished is such a variable which is allowed to be treated as thread-local if it pleases the runtime. It does please it because the
while (!finished);
loop can be rewritten to just
if (!finished) while (true);
If you did any important work inside the loop, it would perform a bit better because the read of finished wouldn't be needlessly repeated, thus possibly destroying one whole CPU cache line.
The above discussion should be enough to answer your immediate question, "is this starvation": the reason the loop doesn't finish is not starvation, but the inability to see the write by the other thread.
There's no starvation here, because you're not doing any work. Starvation means various threads are trying to access the same, limited set of resources. What are the resources each thread is trying to access here? They're not "eating" anything, so they can't starve.
Related
In the following scenario, the boolean 'done' gets set to true which should end the program. Instead the program just keeps going on even though the while(!done) is no longer a valid scenario thus it should have halted. Now if I were to add in a Thread sleep even with zero sleep time, the program terminates as expected. Why is that?
public class Sample {
private static boolean done;
public static void main(String[] args) throws InterruptedException {
done = false;
new Thread(() -> {
System.out.println("Running...");
int count = 0;
while (!done) {
count++;
try {
Thread.sleep(0); // program only ends if I add this line.
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
Thread.sleep(2000);
done = true; // this is set to true after 2 seconds so program should end.
System.out.println("Done!"); // this gets printed after 2 seconds
}
}
EDIT: I am looking to understand why the above needs Thread.sleep(0) to terminate. I do not want to use volatile keyword unless it is an absolute must and I do understand that would work by exposing my value to all threads which is not my intention to expose.
Each thread have a different cached version of done created for performance, your counter thread is too busy making the calculations for count that it doesnt give a chance to reload done.
volatile ensures that any read/write is done on the main memory, always update the cpu cache copy.
Thread.sleep always pause the current thread, so even if 0 your counter thread is interrupted by some time <1ms, that is enough time for the thread to be adviced of done variable change.
I am no Java expert man, I don't even program in java, but let me try.
A thread on stackoverflow explains the Java Memory model: Are static variables shared between threads?
Important part: https://docs.oracle.com/javase/6/docs/api/java/util/concurrent/package-summary.html#MemoryVisibility
Chapter 17 of the Java Language Specification defines the
happens-before relation on memory operations such as reads and writes
of shared variables. The results of a write by one thread are
guaranteed to be visible to a read by another thread only if the write
operation happens-before the read operation. The synchronized and
volatile constructs, as well as the Thread.start() and Thread.join()
methods, can form happens-before relationships.
If you go through the thread, it mentions the "Happens before" logic when executing threads that share a variable. So my guess is when you call Thread.sleep(0), the main thread is able to set the done variable properly making sure that it "Happens first". Though, in a multi-threaded environment even that is not guaranteed. But since the code-piece is so small it makes it work in this case.
To sum it up, I just ran your program with a minor change to the variable "done" and the program worked as expected:
private static volatile boolean done;
Thank you. Maybe someone else can give you a better explanation :P
I know that it is not possible to restart a used Java Thread object, but I don't find an explanation why this is not allowed; even if it is guaranteed that the thread has finished (see example code below).
I don't see why start() (or at least a restart()) method should not be able to somehow reset the internal states - whatever they are - of a Thread object to the same values they have when the Thread object is freshly created.
Example code:
class ThreadExample {
public static void main(String[] args){
Thread myThread = new Thread(){
public void run() {
for(int i=0; i<3; i++) {
try{ sleep(100); }catch(InterruptedException ie){}
System.out.print(i+", ");
}
System.out.println("done.");
}
};
myThread.start();
try{ Thread.sleep(500); }catch(InterruptedException ie){}
System.out.println("Now myThread.run() should be done.");
myThread.start(); // <-- causes java.lang.IllegalThreadStateException
} // main
} // class
I know that it is not possible to
restart a used Java Thread object, but
I don't find an explanation why this
is not allowed; even if it is
guaranteed that the thread has
finished (see example code below).
My guestimation is that Threads might be directly tied (for efficiency or other constrains) to actual native resources that might be re-startable in some operating systems, but not in others. If the designers of the Java language had allowed Threads to be re-started, they might limit the number of operating systems on which the JVM can run.
Come to think of it, I cannot think of a OS that allows a thread or process to be restarted once it is finished or terminated. When a process completes, it dies. You want another one, you restart it. You never resurrect it.
Beyond the issues of efficiency and limitations imposed by the underlying OS, there is the issue of analysis and reasoning. You can reason about concurrency when things are either immutable or have a discrete, finite life-time. Just like state machines, they have to have a terminal state. Is it started, waiting, finished? Things like that cannot be easily reasoned about if you allow Threads to resurrect.
You also have to consider the implications of resurrecting a thread. Recreate its stack, its state, is is safe to resurrect? Can you resurrect a thread that ended abnormally? Etc.
Too hairy, too complex. All that for insignificant gains. Better to keep Threads as non-resurrectable resources.
I'd pose the question the other way round - why should a Thread object be restartable?
It's arguably much easier to reason about (and probably implement) a Thread that simply executes its given task exactly once and is then permanently finished. To restart threads would require a more complex view on what state a program was in at a given time.
So unless you can come up with a specific reason why restarting a given Thread is a better option than just creating a new one with the same Runnable, I'd posit that the design decision is for the better.
(This is broadly similar to an argument about mutable vs final variables - I find the final "variables" much easier to reason about and would much rather create multiple new constant variables rather than reuse existing ones.)
Because they didn't design it that way. From a clarity standpoint, that makes sense to me. A Thread represents a thread of execution, not a task. When that thread of execution has completed, it has done its work and it just muddies things were it to start at the top again.
A Runnable on the other hand represents a task, and can be submitted to many Threads as many times as you like.
Why don't you want to create a new Thread? If you're concerned about the overhead of creating your MyThread object, make it a Runnable and run it with a new Thread(myThread).start();
Java Threads follow a lifecycle based on the State Diagram below. Once the thread is in a final state, it is over. That is simply the design.
You can kind of get around this, either by using a java.util.concurrent.ThreadPoolExecutor, or manually by having a thread that calls Runnable.run() on each Runnable that it is given, not actually exiting when it is finished.
It's not exactly what you were asking about, but if you are worried about thread construction time then it can help solve that problem. Here's some example code for the manual method:
public class ReusableThread extends Thread {
private Queue<Runnable> runnables = new LinkedList<Runnable>();
private boolean running;
public void run() {
running = true;
while (running) {
Runnable r;
try {
synchronized (runnables) {
while (runnables.isEmpty()) runnables.wait();
r = runnables.poll();
}
}
catch (InterruptedException ie) {
// Ignore it
}
if (r != null) {
r.run();
}
}
}
public void stopProcessing() {
running = false;
synchronized (runnables) {
runnables.notify();
}
}
public void addTask(Runnable r) {
synchronized (runnables) {
runnables.add(r);
runnables.notify();
}
}
}
Obviously, this is just an example. It would need to have better error-handling code, and perhaps more tuning available.
If you are concerned with the overhead of creating a new Thread object then you can use executors.
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
public class Testes {
public static void main(String[] args) {
Executor executor = Executors.newSingleThreadExecutor();
executor.execute(new Testes.A());
executor.execute(new Testes.A());
executor.execute(new Testes.A());
}
public static class A implements Runnable{
public void run(){
System.out.println(Thread.currentThread().getId());
}
}
}
Running this you will see that the same thread is used for all Runnable objects.
A Thread is not a thread. A thread is an execution of your code. A Thread is an object that your program uses to create and, manage the life-cycle of, a thread.
Suppose you like playing tennis. Suppose you and your friend play a really awesome set. How would your friend react if you said, "That was incredible, let's play it again." Your friend might think you were nuts. It doesn't make sense even to talk about playing the same set again. If you play again you're playing a different set.
A thread is an execution of your code. It doesn't make sense to even talk about "re-using" a thread of execution for same reason that it makes no sense to talk about re-playing the same set in tennis. Even if another execution of your code executes all the same statements in the same order, it's still a different execution.
Andrzej Doyle's asked, "Why would you want to re-use a Thread?" Why indeed? If a Thread object represents a thread of execution---an ephemeral thing that you can't even talk about re-using---then why would you want or expect the Thread object to be re-useable?
i've been searching the same solution which you seem to be looking for, and i resolved it in this way. if you occur mousePressed Event you can terminate it also reuse it, but it need to be initialized, as you can see below.
class MouseHandler extends MouseAdapter{
public void mousePressed(MouseEvent e) {
if(th.isAlive()){
th.interrupt();
th = new Thread();
}
else{
th.start();
}
}
}
On my machine the following code runs indefinitely (Java 1.7.0_07):
public static void main(String[] args) throws InterruptedException {
Thread backgroundThread = new Thread(new Runnable() {
public void run() {
int i = 0;
while (!stopRequested) {
i++;
}
}
});
backgroundThread.start();
TimeUnit.SECONDS.sleep(1);
stopRequested = true;
}
However, add a single lock object and a single synchronized statement NOT around stopRequested (in fact, nothing occurs in the synchronized block), and it terminates:
public static void main(String[] args) throws InterruptedException {
Thread backgroundThread = new Thread(new Runnable() {
public void run() {
Object lock = new Object();
int i = 0;
while (!stopRequested) {
synchronized (lock) {}
i++;
}
}
});
backgroundThread.start();
TimeUnit.SECONDS.sleep(1);
stopRequested = true;
}
In the original code, the variable stopRequested is "hoisted", becoming:
if (!stopRequested)
while (true)
i++;
However, in the modified version, it seems this optimization is not occurring, why? (In fact, why is synchronized not optimized away entirely?)
VM is unable to reason that the lock is not synchronized by other threads, so it cannot be optimized away.
Per Java Memory Model, all synchronization blocks are totally ordered, and this order (on the same lock) helps to establish happens-before relation. That's why VM can't remove a synchronization block; unless VM can prove that only one thread is ever synchronizing on an object, then all these sync blocks can be removed with no impact on happens-before relation.
If the lock is a local object, VM could do escape analysis to elide the lock. We've been hearing about escape analysis for years, but as the example shows, and as I've tested not very long ago, it doesn't seems to be working yet.
There might be a reason why lock elision isn't being done. The optimization is great for code that uses local Vector or StringBuffer etc. But that's only in old codes; nobody does that for a long time.
Some code might even depend on the stronger pre-java-5 model, in which no lock can be elided ever. There might be many programs, similar to OP's crafted example, that are incorrect in the new model, but have been working for years in the past. Lock elision may break these programs.
While this might look like a memory visibility issue, it is usually a JIT optimisation issue in simple examples. This is because the JIT can detect whether you are modifying the flag in that thread can inline it if you don't. Effectively turning it into an infinite loop.
One way you can tell this is that visibility issues are short lived, usually too short for you to see. While they are random they are usually one micro-second to a milli-second. i.e. until the thread context switches and when it runs again it doesn't keep the old value with it. The fact you can see examples where it consistently turned into an infinite loop which never "detects" the change is a give away.
If you just slow down the loop with a Thread.sleep(10) this can prevent it running long enough to be compiled. It has to loop 10,000+ times to be optimised. This usually "fixes" the problem.
Adding thread safety code such as using a volatile variable or adding a synchronized block can prevent optimisation from being made.
My component integrates to a third-party component. I have to override the onTick() method which is called by a high-priority Thread of the third-party component. Sample code:
#Override
public void onTick() {
// do many useful operations
}
In certain scenarios, this onTick() method should not perform those "many useful operations", because their results are discarded. In fact, the functionality of onTick() is not needed at all in that case, but the third-party component does not offer any "pause" or "sleep" functionality. It calls onTick() all the time. This means that CPU time is used up unnecessarily in these special periods.
The most straightforward solution would be to send a signal to onTick() and make its thread sleep via an Object.wait() in a proper synchronized block. However, the documentation of the third-party component states that its Thread should not be sent to waiting state arbitrarily.
Is there any solution to save CPU resources in this case? That is, to let others use the CPU? I created the following solution, but I'm not sure it allows to save any CPU. (Nonetheless, at least, it should save other resources used by the "useful operations" section of onTick()).
#Override
public void onTick() {
// mJustUnpaused is volatile. Race condition, but probably harmless (?)
if (mJustUnpaused) {
mJustUnpaused = false;
// THREAD_PRIORITY_DISPLAY is the original
// priority used by the 3rd party Thread
Process.setThreadPriority(Process.THREAD_PRIORITY_DISPLAY);
}
if (!mRunningAllowed) {
return;
}
if (mPauseRequested) { // mPauseRequested is declared as volatile
synchronized (mPauseLock) {
if (mRunningAllowed && mPauseRequested) {
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
mRunningAllowed = false;
mPauseLock.notify();
}
}
return;
}
// do many useful operations
}
The methods for pausing/unpausing (the first one is blocking, the second isn't):
public void pauseWork() {
synchronized (mPauseLock) {
if (mRunningAllowed && !mPauseRequested) {
mPauseRequested = true;
while (mRunningAllowed) {
try {
mPauseLock.wait();
} catch (InterruptedException e) {}
}
} else {
Log.d("RPT", "Already paused or pausing");
}
}
}
public void unpauseWork() {
synchronized (mPauseLock) {
if (!mRunningAllowed) {
mRunningAllowed = true;
mPauseRequested = false;
mJustUnpaused = true;
} else {
Log.d("RPT", "No need to unpause");
}
}
}
Three questions:
Is there a better way to save some CPU time?
Regardless of everything else, is my above code correct (in terms of synchronization and other programming aspects)?
Slightly off-topic, but I don't think it deserves a dedicated question: does changing a Thread's priority have any significant overhead? Are there any general guidelines when such an act can be done? (e.g. how often can it be done, etc.)
Is there a better way to save some CPU time?
I wouldn't even bother with what's there. I agree with Chris Stratton: just avoid doing the actual work, and delete the rest of the other code shown above. Then, use Traceview to see whether or not the overhead of your do-nothing onTick() calls is noticeable. Most likely, it will not be.
But I want to change the thread priority as well
That's not a good idea, as it is not your thread, if I understand the scenario properly. Moreover, I believe that you are going to be called ~300 times regardless, as if the library is coded to call you ~30 times a second, it is likely using a Timer or something else that should be relatively immune to thread priority.
Regardless of everything else, is my above code correct (in terms of synchronization and other programming aspects)?
Personally, I'd use stuff from java.util.concurrent and java.util.concurrent.atomic, rather than low-level wait()/notify()/volatile. Doug Lea is smarter than I am. :-)
As you can tell I'm new to multithreading and a bit stuck here. For my program I need a thread (PchangeThread in the below example) that can be toggled on and off from another thread at any point during execution of the program.
The thread should be suspended on start and resume when pixelDetectorOn() is called.
The two threads will most likely not need to share any data except for a start/stop flag. I included a reference to the main thread anyway, just in case.
However, in the below code the only message that is ever output is "before entering loop", which indicates that the thread never wakes up from wait() for some reason. I'm guessing this is some kind of locking problem but I haven't been able to figure out what exactly is going wrong. Locking on this.detector from the main thread gives me the same result. Also I'm wondering if the wait()/notify() paradigm is really the way to go for suspending and waking the thread.
public class PchangeThread extends Thread {
Automation _automation;
private volatile boolean threadInterrupted;
PchangeThread(Automation automation)
{
this._automation = automation;
this.threadInterrupted = true;
}
#Override
public void run()
{
while (true) {
synchronized (this) {
System.out.println("before entering loop");
while (threadInterrupted == true) {
try {
wait();
System.out.println("after wait");
} catch (InterruptedException ex) {
System.out.println("thread2: caught interrupt!");
}
}
}
process();
}
}
private void process()
{
System.out.println("thread is running!");
}
public boolean isThreadInterrupted()
{
return threadInterrupted;
}
public synchronized void resumeThread()
{
this.threadInterrupted = false;
notify();
}
}
resumeThread() is called from the main thread the following way:
public synchronized void pixelDetectorOn(Context stateInformation) {
this.detector.resumeThread();
}
detector is a reference to an instance of PchangeThread.
The "detector"-thread is instantiated in the program's main module the following way:
detector=new PchangeThread(this);
As you said, you need to protect access to the shared flag. You declared threadInterrupted volatile, but than are still using syncronized. You only need one. I prefer to just use syncronized as it makes things simpler. Multi-threading is complicated enough, keep it simple unless you know you need more complicated controls. This means that any time threadInterrupted is read or written to, the access should be synchronized. Currently, you are not doing that in setThreadInterrupt() and isThreadInterrupted().
Secondly, you want to synchronize on as small of a code block as possible. Inside of run(), you are synchronizing over the inner loop. In actuality, you only need to to synchronize on the read of threadInterrupted. When the implementation of isThreadInterrupted() is fixed as mentioned above, you can use that directly and remove the synchronized block from the inner loop.
The fact that you are synchronizing on the inner loop, is the error that is causing your code to never print "thread is running!". PchangeThread acquires the lock on itself and calls wait() to suspend the thread. However, the thread is still holding the lock at this point. At some point later, the main thread calls resumeThread() in order to restart the thread. However, that method can not begin its execution because it must first wait to acquire the lock. However, it will never get the lock until the PchangeThread is notified.
You are providing two ways to set threadInterrupted, but only one of them notifies the thread when the value is set to false. Do you really need setThreadInterrupt()? I expect you don't. If you keep it, it should act the same as resumeThread() when the argument is false.
Lastly, it is better to lock on a private object instead of the instance itself. You have complete control over the private lock object. However, anyone with a reference to your thread instance could also use it as the lock for a synchronized block, which could potentially lead to a hard to find deadlock.
Your code altered to use my edits:
public class PchangeThread extends Thread {
private final Object _lock = new Object();
Automation _automation;
private final boolean _threadInterrupted;
PchangeThread(Automation automation)
{
_automation = automation;
_threadInterrupted = true;
}
#Override
public void run()
{
while (true) {
System.out.println("before entering loop");
while (isThreadInterrupted()) {
try {
wait();
System.out.println("after wait");
} catch (InterruptedException ex) {
System.out.println("thread2: caught interrupt!");
}
}
process();
}
}
private void process()
{
System.out.println("thread is running!");
}
public boolean isThreadInterrupted()
{
synchronized (_lock) {
return _threadInterrupted;
}
}
public void resumeThread()
{
synchronized (_lock) {
_threadInterrupted = false;
notify();
}
}
}
I personally would ask myself the following question in this case: Is the
isInterrupted
flag set only by the main thread e.g. the worker thread just reads it and decides whether to wait or not based on the flag BUT doesn't update it. Or can it be set by both the main thread and the worker thread.
If it is the former - go for a volatile boolean. That way the worker thread will not cache the volatile's value and will always read it from memory. This won't create a race condition because only 1 thread will be updating it - the main one. Think of it as a publish/subscribe scenario.
If you scenario falls in the latter category - use an AtomicBoolean variable. Both cases are going to be more efficient than the synchronized keyword, since you won't acquire any locks but in the case of Atomic* variables you will be utilizing CAS operations which are more lightweight than lock acquisition.
Your code is not wrong (though is not ideal).
I ran it and it prints all the expected messages. Likely, you just do not invoke resumeThread().
A couple of advises:
do not sync on Thread, make a Runnable and sync on it.
you want to start some computation, but what are the data to compute? Looks like they go in a separate way. This is a ground for errors. Use single channel for both data and control. The preferred way is to use a Queue for such a channel. For example, LinkedBlockingQueue is already synchronized in a proper way.
I doubt that anyone will read this, but just in case someone's interested in knowing:
When I checked the debugger log I noticed something strange - it read "debugging stopped on uncompilable source code: )Void;". Since I couldn't think of anything in my source that could have caused this error , I guessed that Netbeans had a problem with some part of the external code I was using (it was not caused by a breakpoint and the project compiled fine!). So, I just updated the third party library I'm using to it's latest version. And behold: after that I suddenly got a null pointer exception when I called resumeThread()!. I checked the rest of my code and quickly found the bug (indeed the reference to the thread was null).
So, to sum it up: The strange behaviour was caused by a minor bug in my program, but something in the external jar led to the suppression of the exception that should have been thrown. Just out of curiosity I double checked by downgrading the jar and "unfixing" the bug and again, the exception was swallowed and the debugger exited with the above mentioned strange message.
Netbeans version 7.1.1