I have a small program presenting the user with a GUI to select a file, the program then executes based on the files contents and presents the results accordingly.
This is the loop running in the main thread (the main() method):
do {
args = fg.getFile();
} while (!fg.started);
fg.started is a boolean variable set to true when the user has selected a file and presses the "start" button.
However, this does not work UNLESS I put a random task inside the loop:
do {
args = fg.getFile();
System.out.println("");
} while (!fg.started);
This works.
Can anyone explain to me why this is?
I'm aware of a solution involving the Thread class, with notify() and wait() etc, but now I'm just curious about this.
fg.started is a boolean variable set to true when the user has selected a file and presses the "start" button.
However, this does not work UNLESS I put a random task inside the loop:
That's because two threads are accessing the started field without memory synchronization. You don't show the definition of fg.started but I suspect that you need to make sure that it is volatile. You also might consider switching to an AtomicBoolean. Here's the Java tutorial about memory synchronization.
volatile boolean started;
The issue with multi-threaded applications is that parts of your program can run in different processors with their own local memory cache. Whenever threads modify or access shared fields there needs to be explicit synchronization to ensure that they aren't just looking at the local cached value of the field.
It is working when you add a System.out.println(...) because the PrintStream's methods are synchronized so you are adding indirect memory synchronization.
making getFile() synchronized fixed it, thanks. Care to explain why? :)
Because, like the System.out.println(...) you are adding indirect synchronization.
You should syncronize the access of fg otherwise this may happen:
Thread1 could possibly become active, access and therefor block fg, and then get paused.
Thread2 becomes active, can't access fg and get's deactivated immediately.
Thread1 is active again, finishes the task an may instantaniously reaccess fg, then pause.
Thread2 becomse active and ... damn! fg is locked again!
If you need help/instructions on concurrency/parallel execution, see Oracle - Syncronization for information.
Related
I have a controller thread that is permanently in synchronized(lock): It does a calculation step, then it does wait(1000), then it checks if more work is to be done. If so, it does another step and waits(1000). If not, it just waits(1000) straightaway. (Mind that I'm using wait, not sleep.)
Sometimes, the calculation steps called by the controller ask the controller to call them many times in a row - that's a high performance mode lasting for multiple seconds. During this time, no other thread (e.g. Swing) could alter data used by this controller thread. Swing would now hang if it tried to do this!
I want to keep the balance between high performance and good fluidity.
Therefore, I want to add wait(1) in this high performance mode loop.
QUESTION: Will a thread waiting to grab the lock achieve dominance with ABSOLUTE certainty, if I sprinkle these wait(1) calls into the calculation loop?
QUESTION: Will a thread waiting to grab the lock achieve dominance with ABSOLUTE certainty, if I sprinkle these wait(1) calls into the calculation loop?
The short answer is sort of in that you are always getting the lock when lock.wait(1) returns. However, I don't think you understand how to use lock and notify to gain control over a shared resource. To call lock.wait(1) you need to own the lock to start with.
The call releases the lock and returns either if lock.notify() or notifyAll() was called or if the timeout expires and (NOTE) the lock is available to be locked again. This means that if someone else owns the lock for a long period of time, the wait(...) method won't return unless the lock is released – which could be for many milliseconds. It is designed to help threads coordinate between themselves.
If the question is "does calling wait(1) in a calculation loop only give the lock to other people for 1ms" then the answer is no.
If you have a resource that can only be used by one thread at a time then the other threads will need to wait until it is available. You hope that each thread uses the resource for a short amount of time so the waiting is small.
You can protect the resource using a couple of different mechanisms. The easiest is to just put a synchronized block around its use. This protects it from race conditions and ensures that any changes to the resource gets published to main memory in all threads. No wait or notify calls are required using this mechanism.
Another way of doing it is to use lock.wait(...) and lock.notify(). This mechanism is required when (for example) threads are consuming from a collection and need to wait for there to be entities added. In this case, when a thread adds an entity to the collection it calls lock.notify() and any thread(s) waiting for work in lock.wait() will be notified that there is work to do and will awaken.
The use of the lock.wait(...) timeout argument means that threads can wait for a certain amount of time for the resource to be available before giving up. In the queue processing example above, the threads may need to check if the application is shutting down every second or so. So they call lock.wait(1000), test if the shutdown flag has been set, and if not they can check for work to be done and then call wait again. Just because you are calling lock.wait(1) doesn't ensure any sort of lock "dominance" and doesn't mean that the method returns after 1ms.
If you want to use wait and notify signaling then you would need a secondary variable to check to see if the resource is in use. The following example uses an inUse boolean field.
private final Object lock = new Object();
private boolean inUse = false;
...
synchronized (lock) {
while (inUse) {
lock.wait();
}
inUse = true;
}
// use the resource
...
synchronized (lock) {
inUse = false;
lock.notify();
}
Notice that the example tests for inUse in a while loop and not just an if. This is an important pattern and is needed because you could be notified but another thread might have gotten access to the resource while you were waiting.
A strange thing. Code below works, if the condition desiredHealth < p.getFakeHealth() is true, it DOES SOMETHING.
#Override
public void run(){
while(game_running){
System.out.println("asd");
if(desiredHealth < player.getFakeHealth()){
DOES SOMETHING
}
}
BUT... without 'System.out' it does not work. It doesn't check the condition.
It is somehow on lower priority, or something.
#Override
public void run(){
while(game_running){
if(desiredHealth < player.getFakeHealth())
DOES SOMETHING
}
}
I'm new to threads, so please, dont shout at me :)
Just for info, this thread is a normal class which 'extends Thread' and yes - it is running. Also 'game_running' is true all the time.
the variable must be volatile because the volatile keyword indicates that a value may change between different accesses, even if it does not appear to be modified.
So, be sure game_running is declared volatile.
Explanation:
Ahh, I have seen this on an older SO question. I'm gonna try to find it for further information.
Your problem is happening because the output stream's print is blocking the current thread and one of the desiredHealth and player.getFakeHealth() expressions get a second chance to be evaluated/changed by other thread and voilà! Magic happens. This is because printf on glibc is synchronized, so when you print, the rest of the operations are waiting for the println operation to complete.
Resolution:
We don't have enough context(who is initializing the player, who does the changes and so on), but it's obvious that you have a threading issue, something is not properly synchronized and your background thread works with bad values. One of the reasons might be that some variables are not volatile and if your background thread reads a cached value, you already have a problem.
One of the topics you need to study regarding concurrency is the Java memory model (that's the official spec but I suggest you read a tutorial or a good book, as the spec is rather complicated for beginners).
One of the issues when different threads work with the same memory (use the same variable - e.g. when one is writing into a variable, the other makes decisions based on their value) is that for optimization reasons, the values written by one thread are not always seen by the other.
For example, one thread could run on one CPU, and that variable is loaded into a register in that CPU. If it needed to write it back to main memory all the time, it would slow processing. So it manipulates it in that register, and only writes it back to memory when it's necessary. But what if another thread is expecting to see the values the first thread is writing?
In that case, it won't see them until they are written back, which may never happen.
There are several ways to ensure that write operations are "committed" to memory before another thread needs to use them. One is to use synchronization, another is to use the volatile keyword.
System.out.println() in fact includes a synchronized operation, so it may cause such variables to be committed to memory, and thus enable the thread to see the updated value.
Declaring the variable as volatile means that any changes in it are seen by all the other threads immediately. So using volatile variables is also a way of ensuring that they are seen.
The variable that is used to decide whether to keep the thread running should normally be declared volatile. But also, in your case, the variables desiredHealth (if it's written by a different thread) and whatever variables getFakeHealth() relies on (if they are written by a different thread) should be volatile or otherwise synchronized.
The bottom line is that whatever information is shared between two threads needs to be synchronized or at the very least use volatile. Information that is not shared can be left alone.
In my Android App there is an activity that contains a runnable inner class.
From this activity a new Thread running the inner class is created/started.
This thread executes this loop:
while (run) {
...
}
The state of the boolean "run" should be changed from both threads.
Thats why I put it into the activity class like this:
private static volatile boolean run;
I would like to know if this is a correct way of controlling a thread.
Do both threads use the same variable in the memory?
As neither checking nor setting a boolean is an atomic operation for the cpu, is it possible, that one thread checks "run" while the other thread is changing its state?
A thread will stop itself if the task you placed in the inner Runnable class was completed. So, keeping the Runnable alive will make the thread alive too, i.e. using while loop. And volatile boolean controls the change of run variable easily.
Do both threads use the same variable in the memory?
Yes. You haven't shown us much code, but since the variable is static, you've shown us enough. A static variable only exists in one place. Any code that can see it anywhere in your program is seeing the same variable.
I would like to know if this is a correct way of controlling a thread.
It is a fine way of signalling a thread.
The only reason why you might want to do differently is if the thread is not able to check the run variable often enough. Especially, if the thread waits for anything.
In that case, you might want to look into thread.interrupt() Interrupting any thread while it is waiting for something (in most cases) will cause the method that was waiting to throw an InterruptedException. That affords your thread the opportunity to check whether or not it still should be running.
I am actually looking for an easier way to kill the thread not matter where the thread is running at. But most of the solutions in internet point me to use boolean flag to control the execution of the thread, if I want to stop the thread then set the boolean variable to false.
But what if the task that in the runnable is a LONG linear task, which mean the task is not repeating? In that case, it is not so easy to create a 'while' loop to cover the whole block of task.
It is really so temptative to use Thread.stop but the warning "Deprecated" seem like quite dangerous to use. I have read through this article
Why Are Thread.stop, Thread.suspend, Thread.resume and Runtime.runFinalizersOnExit Deprecated?
but I can't understand
If any of the objects previously protected by these monitors were in
an inconsistent state, other threads may now view these objects in an
inconsistent state. Such objects are said to be damaged.
What does the "inconsistent state" mean? I appreciate if anyone can explain about this.
I want to extend my question to a more lower level of view, let say i = i + 1; in JVM (perhaps assembly language alike), maybe this Java statement will be split into few smaller instructions, for example like move i ; add i ; get i into memory 0x0101 (This is an example! I totally don't know assembly language!)
Now, if we call thread.stop, where actually will it stop at? Will the thread stop after a COMPLETED Java statement, or could be in the middle of the "assemble language"? If the answer is the second, could it be reason that we said
Such objects are said to be damaged.
?
Ok, my question is kind of confused, hope someone can understand and explain. Thanks in advance.
"Damaged object" is a high-level concept, it doesn't happen at the JVM level. A programmer designs his class with thread safety in mind by guarding critical sections with locks. It is an invariant of his class that each critical section either runs in full, or doesn't run at all. When you stop a thread, a critical section may have been interrupted in the middle, so disrupting the invariant. At that moment the object is damaged.
Stopping a thread conceals many more dangers, like no cleanup performed, no acquired resources released, etc. If a thread doesn't give up what it is doing, there is no way to make it stop without compromising the entire application.
In practice, whenever one faces the need to run alien code that may need to be forcefully aborted, this must be done in a separate process because killing a process at least performs OS-level cleanup and does a much better job of containing the damage.
The "inconsistent state" means state of data as your application cares about, state that your application logic have carefully produced by making your application thread-safe with locks/monitors etc.
Imagine you have this simple method:
public synchronized void doSomething()
{
count++;
average = count/total;
}
This method, along with other methods are synchronized, as multiple threads are using this object.
Perhaps there's a
public synchronized AverageAndCount getMeasurement()
{
return new AverageAndCount(average, count);
}
This assures that a thread can't read an incomplete measurement, i.e. if the current measurement is in the process of being calculated inside e.g. doSomething(), getMeasurement() will block/wait until that's finished.
Now, imagine the doSomething is run in a thread, and you call .stop() on that thread.
So the thread might be stopped right after it performs count++;, the monitor that's held is unlocked and the method terminates and average = count/total; is not executed,
That means the data is now inconsistent. Anyone calling getMeasurement() afterwards will now get inconsistent data.
Note also that at this point it is not very relevant whether this happens at a java statement level, or at a lower level, the data can be in an inconsistent state that you can't reason about in any case.
I'm no expert but this is what I think.
If you use Thread.stop() you cause the ThreadDeath exception that will cause all monitors to be released.
Since you provoke an exception you are applying an unnatural behaviour to the state of things.
Other threads relying on those monitors could enter in an inconsistent situation because they were not expecting it. And I don't think you can even anticipate the monitors releasing order.
I believe the concern is that the thread may be in the middle of a synchronize block performing multi-step updates to an object's members. If the thread is stopped abruptly, then some updates will have occurred but not others and now the object's state may render it unusable.
I have my doubts that the ThreadDeath handling will release a Lock backed by the AbstractQueuedSynchronizer which could leave the application on the path to a sort of deadlock.
At any logical point in your long sequence of code you can simply add:
if (Thread.interrupted()) {
throw new InterruptedException();
}
...this will exit execution at this point if it is determined that Thread.interupt() was called on the Thread executing the long running task.
It's not clear way to stop the thread.actually deprecated the stop() method whenever run() method is completed or any exception is occurred then thread is stop.by using the boolean flag variable .Bydefault "false"
I have the following situation. I have an application that runs mostly on one thread. It has grown large, so I would like to run a watchdog thread that gets called whenever the main thread changes into a different block of code / method / class so I can see there is "movement" in the code. If the watchdog gets called by the same area for more than a second or a few, it shall set a volatile boolean that the main thread reads at the next checkpoint and terminate / restart.
Now the problem is getting either of the threads to run somewhat at the same time. As soon as the main thread is running, it will not let the watchdog timer count properly. I was therefore thinking of yielding every time it calls the watchdog (so it could calculate time passed and set the value) but to no avail. Using Thread.sleep(1) instead of Thread.yield() works. But I don't want to have several areas of code just wasting calculation time, I am sure I am not doing it the way it is meant to be used.
Here a very simple example of how I would use Thread.yield(). I do not understand why the Threads here will not switch (they do, after a "long" and largely unpredictable time). Please give me an advice on how to make this simple example output ONE and TWO after each other. Like written before, if I switch yield() with sleep(1), it will work just like I'd need it to (in spite of waiting senselessly).
Runnable run1 = new Runnable(){
public void run(){
while(true){
System.out.println("ONE");
Thread.yield();
}
}
};
Runnable run2 = new Runnable(){
public void run(){
while(true){
System.out.println("TWO");
Thread.yield();
}
}
};
Thread tr1 = new Thread(run1);
Thread tr2 = new Thread(run2);
tr1.start();
tr2.start();
Thread.yield()
This static method is essentially used to notify the system that the
current thread is willing to "give up the CPU" for a while. The
general idea is that:
The thread scheduler will select a different thread to run instead of
the current one.
However, the details of how yielding is implemented by the thread
scheduler differ from platform to platform. In general, you shouldn't
rely on it behaving in a particular way. Things that differ include:
when, after yielding, the thread will get an opportunity to run again;
whether or not the thread foregoes its remaining quantum.
The take away is this behavior is pretty much optional and not guaranteed to actually do anything deterministically.
What you are trying to do is serialize the output of two threads in your example and synchronize the output in your stated problem ( which is a different problem ), and that will require some sort of lock or mutex to block the second thread until the first thread is done, which kind of defeats the point of concurrency which is usually the reason threads are used.
Solution
What you really want is a shared piece of data for a flag status that the second thread can react to the first thread changing. Preferably and event driven message passing pattern would be even easier to implement in a concurrently safe manner.
The second thread would be spawned by the first thread and a method called on it to increment the counter for which block it is in, you would just use pure message passing and pass in a state flag Enum or some other notification of a state change.
What you don't want to do is do any kind of polling. Make it event driven and just have the second thread running always and checking the state of its instance variable that gets set by the parent thread.
I do not understand why the Threads here will not switch (they do, after a "long" and largely unpredictable time). Please give me an advice on how to make this simple example output ONE and TWO after each other. Like written before, if I switch yield() with sleep(1), it will work just like I'd need it to (in spite of waiting senselessly).
I think this is more about the difference between ~1000 println calls in a second (when you use sleep(1)) and many, many more without the sleep. I think the Thread is actually yielding but it may be that it is on a multiple processor box so the yield is effectively a no-op.
So what you are seeing is purely a race condition high volume blast to System.out. If you ran this for a minute with the results going to a file I think you'd see a similar number of "ONE" and "TWO" messages in the output. Even if you removed the yield() you would see this behavior.
I just ran a quick trial with your code sending the output to /tmp/x. The program with yield() ran for 5 seconds, generated 1.9m/483k lines, with the output sort | uniq -c of:
243152 ONE
240409 TWO
This means that each thread is generating upwards of 40,000 lines/second. Then I removed the yield() statements and I got just about the same results with different counts of lines like you'd expect with the race conditions -- but the same order of magnitude.