Why could this code fail? - java

While reviewing this question I noticed this code:
class MyThread extends Thread {
private boolean stop = false;
public void run() {
while(!stop) {
doSomeWork();
}
}
public void setStop() {
this.stop = true;
}
}
However I don't understand why would this fail. Do other threads not get access to the "actual" stop variable?

The JIT compiler can re-order reads and writes in an application so long as
the actions are sequentially consistent and
the altered actions do not violate intra-thread semantics.
That is just a fancy way of saying, all actions should appear to happen the same way as if it were executed by only a single thread. So you can get the JIT to recompile your code to look like this
class MyThread extends Thread {
private boolean stop = false;
public void run() {
if(!stop){
while(true){
}
}
}
This is a legal optimization called hoisting. It still acts the same as if serial but offers surprising results when using multiple threads.
By declaring a field volatile you are telling Java not to execute any re orderings. Along with the memory consistency as mentioned by Nathan Hughes

The instance variable stop needs to be volatile, otherwise there's no guarantee the other threads will see changes to it. There are a lot of conflicting interests at work: threads want a consistent view of the program state, CPUs want to be able to cache data, the JVM wants to be able to reorder instructions. Making the instance variable volatile means that it can't be cached and that happens-before relationships are established that limit instruction reordering.
See this other answer (+1) for a good example of what reordering may happen without marking the variable volatile.
(By the way using interruption for thread cancellation is preferable to using an instance variable.)

The variable stop must be declared as volatile.
Although i prefer using interrupt to stop a thread.

Other threads are not guaranteed to see updated values of stop - you need to establish a "happens before" relationship. The simplest way would be to make stop volatile.

Related

Do I have to use synchronized on main thread methods?

To be more specific my question is if the main thread methods are already synchronized?
For example:
#MainThread
class MyClass{
private Object o = null;
#MainThread
MyClass(){
}
#MainThread
public Object getObjectFromMainThread(){
return this.o.getObj2();
}
#MainThread
public void setObjectFromMainThread(Object obj){
obj.set(1);
this.o=obj;
}
#AnyThread
public synchronized Object getObjectFromAnyThread(){
return this.o;
}
#AnyThread
public synchronized void setObjectFromAnyThread(Object obj){
this.o=obj;
}
}
The methods getObjectFromMainThread and setObjectFromMainThread which are called only from main thread are not synchronized. Does it need to be synchronize as well or is not necessary?
The answer to your immediate question is yes, you will have to synchronize the getObjectFromMainThread and setObjectFromMainThread methods in your example. The answer to why there's this need is a mighty deep rabbit hole.
The general problem with multithreading is what happens when multiple threads access shared, mutable state. In this case, the shared, mutable state is this.o. It doesn't matter whether any of the threads involved is the main thread, it's a general problem that arises when more than one thread is in play.
The problem we're dealing with comes down to "what happens when a thread is reading the state at the same time that one or more threads are writing it?", with all its variations. This problem fans out into really intricate subproblems like each processor core having its own copy of the object in its own processor cache.
The only way of handling this is to make explicit what will happen. The synchronized mechanism is one such way. Synchronization involves a lock, when you use a synchronised method, the lock is this:
public synchronized void foo() {
// this code uses the same lock...
}
public void bar() {
synchronized (this) {
// ...as this code
}
}
Of all the program code that synchronizes on the same lock, only one thread can be executing it at the same time. That means that if (and only if) all code that interacts with this.o runs synchronized to the this lock, the problems described earlier are avoided.
In your example, the presence of setObjectFromAnyThread() means that you must also synchronize setObjectFromMainThread(), otherwise the state in this.o is accessed sometimes-synchronized and sometimes-unsynchronized, which is a broken program.
Synchronization comes at a cost: because your locking bits of code to be run by one thread at a time (and other threads are made to wait), you remove some or all of the speed-up you gained from using multi-threading in the first place. In some cases, you're better off forgetting multi-threading exists and using a simpler single-threaded program.
Within a multi-threaded program, it's useful to limit the amount of shared, mutable state to a minimum. Any state that's not accessed by more than one thread at a time doesn't need synchronization, and is going to be easier to reason about.
The #MainThread annotation, at least as it exists in Android, indicates that the method is intended to be accessed on the main thread only. It doesn't do anything, it's just there as a signal to both the programmer(s) and the compiler. There is no technical protection mechanism involved at run time; it all comes down to your self-discipline and some compile-time tool support. The advantage of this lack of protection is that there's no runtime overhead.
Multi-threaded programming is complicated and easy to get wrong. The only way to get it right is to truly understand it. There's a book called Java Concurrency In Practice that's a really good explanation of both the general principles and problems of concurrency and the specifics in Java.

Simple thread crashes Android app

I found a very peculiar issue when creating an launching a thread inside an Android app.
If I have the following class thread:
public class TroubleThread extends Thread{
boolean running;
public boolean isRunning() {
return running;
}
public void setRunning(boolean running) {
this.running = running;
}
#Override
public void run() {
while (isRunning()){
}//end while
}//end run
}
and add it somewhere in the Activity's onCreate(...) method like:
public class MyActivity extends Activity {
TroubleThread myThread;
#Override
public void onCreate(Bundle savedInstanceState) {
//....
myThread = new TroubleThread();
myThread.setRunning(true);
myThread.start();
}
}
the app will crash.
But if I change the run() method to:
#Override
public void run() {
while (running){ //NOTE THE USE OF DIRECT FIELD ACCESS INSTEAD OF METHOD
}//end while
}//end run
it stops from crashing.
Even if I solved my problem by using locks, notify() and wait() the question still remains:
Why when using direct access to the field the app continues to work while when using the method it crashes?
First of all, since you did not provide a MCVE, other people cannot reproduce your problem. That is unfortunate because it means we cannot be sure what the real cause of the problem is. We can only propose hypotheses.
Some people have hypothesized that your problem is due to something else; e.g. an infinite loop on the GUI thread. That is plausible, but there is no clear evidence for this. (And we can't see the code ....)
My hypothesis is that this is a "memory visibility" issue. The Java Language Specification has a chapter that defines the circumstances under which one thread is guaranteed to see a value written to memory by another thread. The rules are rather complicated and technical, but the essence is that you need to analyzing whether there is a happens before relationship between a memory write by one thread and a subsequent memory read by another thread. A number of things will give you that relationship:
the threads write / reading a shared volatile variable
the threads synchronizing using the same lock
a thread start
a thread join
completion of a constructor (for final variables)
However, none of these things exist in your program with respect to the running variable. This means that there is no guarantee that the thread that is looping on the running variable will see the results of the setRunning call made by the other thread:
It might see the changes immediately
It might see the changes later
It might never see them
All three behaviors are possible .... in the absence of a happens before relationship.
So why does one version of the code behave differently to the other?
We can't be sure. To actually be sure, someone would need to do a deep analysis of the native (machine) code for your example. It could be something to do with (legal) reordering that the optimizer has done in one case and not the other. It could be a subtle timing effect.
But either way, the JLS says the the compiler is not obliged to make sure that the write is visible. Why? Because this code breaks the rules of the memory model.
Solutions:
In this case, the simplest solution is to declare running as volatile.
Another solution is to declare isRunning() and setRunning as synchronized methods.
Either of these are sufficient to provide the happens before relationship ... and guarantee that isRunning() sees the update made by setRunning().

Is volatile needed for a lazy boolean shutdown flag in Java?

Assume the following code
public class Singleton {
boolean shuttingDown = false;
void action() {
if (shuttingDown) {
throw new RuntimeException("already shutting down");
}
// do some more stuff
}
// Called by a single thread only
void onShutDown() {
shuttingDown = true;
// perform some more actions to remedy the class
}
}
Basically I want to block all upcoming calls to action() with an exception.
I know that setting shuttingDown is an atomic operation. However the question is if I would need to make shuttingDown volatile to make the change visible to the other threads, which might be re-used from a thread pool.
I saw this oracle tutorial and also the javadoc on AtomicBoolean.
However the latter uses volatile, too. I set the value only once in a single thread, so I don't need the locking mechanisms provided by AtomicBoolean.
I just want to make the change visible to all threads as soon as the variable is updated.
As far as I understand the oracle tutorial, the update operation is atomic, that is no other thread can intecept while setting the value. The question is, when will the updated value be populated to the other threads (if at all?).
The short answer is yes, you must make it volatile.
Although the operation is atomic, for it to be guaranteed visible to other threads you need to establish a happens before relationship. Volatile is the simplest way to do this.

What is the importance of synchronized method in stopping one Thread from another?

From the book "Effective java" i have following famous code of stopping one thread from another
public class StopThread {
private static boolean stopRequested;
private static synchronized void requestStop() {
stopRequested = true;
}
private static synchronized boolean stopRequested() {
return stopRequested;
}
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);
requestStop();
}
}
A line is written there that is "synchronization has no effect unless both read and write
operations are synchronized."But it is clear that if we don't use synchronized keyword with method requestStop the code will work fine,i.e,it terminates nearly after 1 second which is desired.One thing more here is that if we don't synchronize both the method we will(most probably) go into infinite loop because of code optimization.So my questions are:-
1.How and in what scenario things can go wrong if we don't synchronize 'stopRequested' method?Although here if we don't synchronize it,the program runs as desired,i.e,it terminates nearly in 1sec.
2.Does synchronized keyword enforces the VM to stop optimization each time?
1.How and in what scenario things can go wrong if we don't synchronize 'stopRequested' method?Although here if we don't synchronize it,the program runs as desired,i.e,it terminates nearly in 1sec.
Things can go wrong if JVM decides to optimize the code within the run method of your backgroundThread. The read of stopRequested() can be reordered for optimization by JVM because of which it may never call the stopRequested() method again. But these days almost all JVM implementations take care of this and hence without making stopRequested as synchronized your code will still run fine. Also point to be noted here is that if you donot make stopRequested synchronized then the change done to stopRequested boolean variable may not be seen immediately by other non synchronized threads. Only if you used synchronization can the other threads immediately detect any change as an entry into synchronized method clears the cache and loads the data from the memory fresh. This immediate detection of memory changes is important in a highly concurrent system
2) Does synchronized keyword enforces the VM to stop optimization each time?
Synchronized keyword doesnot enforce VM to stop optimization but it makes it to adhere to the things listed below. VM can still do an optimization but it has to take care of the below things.
Synchronization effectively does the following things:-
It guarantees happens before relationship. If one action happens-before another, then the first is visible to and ordered before the second.
It guarantees memory visibility that is all the modifications done within the block which may be cached are immediately flushed before the exit of synchronization block which results in any other synchronized thread to see the memory updates immediately. This will be important in case of highly concurrent systems.
Changes by a thread to a variable are not necessarily seen right away by other threads. Using synchronized here makes sure that the update by one thread is visible to the other thread.
1) The change would possibly not become visible to the other thread. In the absence of synchronization or volatile or atomic fields there's no assurance when the other thread will see the change.
2) The synchronized keyword helps the VM decide on limits on instruction reordering and on what the VM can optimize.
Testing this on your machine will not necessarily display the same results as using a server with more processors. Different platforms may do more optimizing. So just because it works on your machine doesn't necessarily mean it's ok.
1.How and in what scenario things can go wrong if we don't synchronize 'stopRequested' method?
Assume if one thread is writing (updating) the field stopRequested, now before the first thread updates the value of stopRequested from requestStop(), another thread can read the value of stopRequested by calling stopRequested() (if stopRequested() was not synchronized. Thus it would not get the updated value.
2.Does synchronized keyword enforces the VM to stop optimization each time?
Not always, Escape Analysis implemented from JDK6U23 also plays a part in this.
Synchronization creates a memory barrier which ensures a happens-before relationship. i.e, any block of code executed after a synchronized block is sure to have the updated value (changes made earlier are reflected).
Statements can be executed out-of-order within a synchronized block to improve efficiency provided the happens-before holds good. On the other hand a synchronized block can be removed by the JVM if it determines that the block can be accessed only by a single thread.
Just make stopRequested volatile. Then method stopRequest does not have to be synchronized, because it does not change anything.

Using 'this' versus another object as lock in synchronized block with wait and notify

I have two blocks of code, one waits for the other to notify it.
synchronized(this) {
wait();
}
and
while(condition) {
//do stuff
synchronized(this) {
notify();
}
}
Weirdly enough that didn't wait for the notify while this did:
synchronized(objectLock) {
objectLock.wait();
}
and
while(condition) {
//do stuff
synchronized(objectLock) {
objectLock.notify();
}
}
I'm very curious about the difference of both sets, and why the first one worked while the other didn't. Note that the two blocks reside in two different threads on two different methods (if that helps).
I hope someone could explain why this is so. I edited my question so it would be more detailed.
It didn't work because you synchronized on this which in two different threads pointed to two different Thread objects.
Synchronization with wait() and notify() would only work properly when you synchronize on the same object for locking like the objectLock that you used later on.
EDIT:
If the two thread instances belonged to the same MyThread class then to achieve the effect that you thought you're code was having, you would have to acquire a lock on their class object itself:
synchronized(MyThread.class)
You can use any object you like. However, it is generally clearer to other programmers to see an explicit lock object.
My wild guess as to why this didn't work for you is you had a different this in scope. (ie, in an anonymous function/callback). You can be explicit about which this to use by appending the class name, eg, WonderClass.this - again a reason why this is not as clear. (edit: actually WhateverClass.this won't help you if this really is a different instance)
Also do read this: http://docs.oracle.com/javase/tutorial/essential/concurrency/locksync.html - I generally find it easier to put all the thread-unsafe code into small synchronized methods (which do an implict lock on this)
When you say the two blocks reside in two different threads that makes me think they're not locking on the same object because this is not the same thing. When you name an explicit lock you're using the same thing to lock on.
By the way you should call wait in a loop, like this:
synchronized(someLock) {
while (!someCondition) {
wait();
}
// now the thread has the lock and it can do things
// knowing for sure that someCondition is true
}
Without this you will be vulnerable to spurious wakeups (not all notifications come from your application code) and the order in which wait and notify are called becomes problematic (if you have two threads and one notifies before the other waits then that notification never gets seen).
I'd advise using the Monitor pattern (http://en.wikipedia.org/wiki/Monitor_(synchronization)) anyway, that could save you from errors later on, especially as your use case gets more complex:
class Monitor
{
/** Initialised to `false` by default in Java. */
boolean condition;
synchronized void waitForSomething()
{
while(!condition)
{
wait();
}
}
synchronized void signal()
{
condition = true;
notify();
}
}
That way everything is nicely encapsulated and protected (I don't usually use private modifiers in examples, but you might want to enforce additional "privacy" in your code, specifically making the condition private.)
As you can observe, in my condition loop there is wait() call, as opposed to your example where you have notify() in the loop instead. In most use cases doing what you did with notify is a mistake, although I can't speak for your particular case as you didn't provide us with enough details. I am willing to bet yours is the typical one though, for which the Monitor pattern applies beautifully.
The usage scenario is along the following: thread that wants to wait for something calls waitForSomething and another thread may cause it to continue by invoking signal method which will set the condition flag.

Categories

Resources