Are unresettable "flags" threadsafe in Java? - java

I have been using this pattern for a while, but I only recently came to think that it might not be OK to do this. Basically, I use some variant of this pattern:
public class SampleJavaAsync
{
public SampleJavaAsync() { }
private boolean completed;
public void start()
{
new Thread(new Runnable() {
#Override
public void run() {
//... do something on a different thread
completed = true;
}
}).start();
}
public void update()
{
if (!completed) return;
//... do something else
}
}
*The user is responsible for making sure start is only called once. update is called wherever and whenever.
I've always assumed this is threadsafe in Java, because even though nothing is strictly synchronized, I only ever set completed to true. Once it has been observed to be true, it will not reset to false. It is initialized to false in the constructor, which is by definition thread safe (unless you do something stupid in it). So, is it thread safe to use unresettable flags in this way? (And if so, does it even provide any performance benefits?)
Thanks

Java: it's feasible for update() to not see the update to completed that has already happened. Unless you mark it volatile, the JVM is permitted to do all sorts of things in the name of optimization (namely reordering reads and writes as it sees fit), meaning you could feasibly hit a state where the thread running update() NEVER sees that completed has changed, because it's not marked volatile, and it thinks it can optimize away that pesky write (or defer it).
You would at least run the risk of having inconsistency when it's first set, where, e.g. a call to update() on the same thread could see a different value than the same call from another thread, at the same time.
Better explained:
http://jeremymanson.blogspot.com/2008/11/what-volatile-means-in-java.html
Or, if you're really curious about concurrency in Java, buy a copy of JCIP:
http://jcip.net.s3-website-us-east-1.amazonaws.com/

Related

Does boolean variable need synchronization while checking in the given example?

I'm exploring an example of a simple android game and I have a question about its synchronization logic.
Given two fields:
private boolean mRun = false;
private final Object mRunLock = new Object();
Method setRunning in a worker thread class:
public void setRunning(boolean b) {
synchronized (mRunLock) {
mRun = b;
}
}
And method run in the same class:
public void run() {
while (mRun) {
Canvas c = null;
try {
c = mSurfaceHolder.lockCanvas(null);
synchronized (mSurfaceHolder) {
if (mMode == STATE_RUNNING) updatePhysics();
synchronized (mRunLock) {
if (mRun) doDraw(c);
}
}
} finally {
if (c != null) {
mSurfaceHolder.unlockCanvasAndPost(c);
}
}
}
}
Is it correct to not synchronize mRun in the while statement? I think setRunning might potencially be called while mRun is being checked for true.
I don't think the code is correct.
You should probably do something like:
while (true) {
synchronized (mRunLock) {
if (mRun) break;
}
// ...
}
Without this, you don't have a guarantee that writing to mRun happens-before the read in the condition.
It will sort-of work without it, because you are reading mRun inside a synchronized block inside the loop; provided that read is executed, the value will be updated. But the value you read in the loop expression on the next iteration could be the same value as was read on the previous iteration in the synchronized (mRunLock) { if (mRun) doDraw(c); }.
Critically, it isn't guaranteed to read an up-to-date value on the initial iteration. If false is cached, the loop won't execute.
Making mRun volatile would be easier than using synchronization, though.
You need to keep the 'synchronized' statements. If you don't (though note that android, which isn't really java, may not be adhering to the same memory model as actual java), then any thread is free to make a temporary clone for any field of any instance it wants, and synchronize any writes to the clone at some undefined later point in time with any other thread's clone.
To avoid the issues with these 'clones'*, you need to establish CBCA relationships ("comes before/comes after") - if the thread model ensures that line X in thread A definitely ran after line Y in thread B, then any field writes done by line Y will guaranteed be visible in line X.
In other words, with the synchronized statements, if the mRunLock lock in your run() method has to 'wait' for the setRunning method to finish running, you just established a CBCA relationship between the two, and it's crucial because that means the mRun write done by setRunning is now visible. If you didn't, it may be visible, it may not be, it depends on the chip in your phone and the phase of the moon.
Note that boolean writes are otherwise atomic. So it's not so much about any issues that would occur if you read whilst the field is being written (that is not a problem in itself if the field's type is decreed as being atomic, which all primitives other than double and long are), it's ensuring visibility of any changes.
In plain jane java you'd probably use an AtomicBoolean for this and avoid using any synchronized anything. Note also that nesting synchronized() on different locks (you lock on mSurfaceHolder, and then lock on mRunLock) can lead to deadlocks if any code does it 'in reverse' (locks on mRunLock first, then locks on mSurfaceHolder).
Are you running into any problems with this code, or just wondering 'is it correct'? If the latter: Yes, it is correct.
*) Whilst this clone thing sounds tedious and errorprone, the only alternative is that any field write by any thread is immediately visible by any other thread. That would slow everything waaaaay down; the VM has no idea which writes have the potential to be read soon by another thread, and if you know anything about modern CPU architecture, each core has its own cache that is orders of magnitude (100 to 1000 times!) faster than system memory. This alternative of 'all writes must always be visible everywhere' would pretty much mean that fields can never be in any caches ever. That'd be disastrous for performance. This memory model is therefore basically a necessary evil. There are languages that don't have it; they tend to be orders of magnitude slower than java.

Why is this code not going into an infinite loop as suggested by JSR133?

In JSR-133 section 3.1, which discusses the visibility of actions between threads - it is mentioned that the code example below, which does not utilise the volatile keyword for the boolean field, can become an infinite loop if two threads are running it. Here is the code from the JSR:
class LoopMayNeverEnd {
boolean done = false;
void work() {
while (!done) {
// do work
}
}
void stopWork() {
done = true;
}
}
Here is a quote of the important bit in that section that I'm interested in:
... Now imagine that two threads are created, and that one
thread calls work(), and at some point, the other thread calls stopWork(). Because there is
no happens-before relationship between the two threads, the thread in the loop may never
see the update to done performed by the other thread ...
And here is my own Java code I wrote just so I can see it loop:
public class VolatileTest {
private boolean done = false;
public static void main(String[] args) {
VolatileTest volatileTest = new VolatileTest();
volatileTest.runTest();
}
private void runTest() {
Thread t1 = new Thread(() -> work());
Thread t2 = new Thread(() -> stopWork());
t1.start();
t2.start();
}
private void stopWork() {
done = true;
System.out.println("stopped work");
}
private void work() {
while(!done){
System.out.println("started work");
}
}
}
Although the results from consecutive executions are different - as expected - I don't see it ever going into an infinite loop. I'm trying to understand how I can simulate the infinite loop that the documentation suggests, what am I missing? How does declaring the boolean volatile, remove the infinite loop?
The actual behavior is OS and JVM specific. For example, by default, Java runs in client mode on 32-bit Windows and in server mode on the Mac. In client mode the work method will terminate, but will not terminate in server mode.
This happens because of the Java server JIT compiler optimization. The JIT compiler may optimize the while loop, because it does not see the variable done changing within the context of the thread. Another reason of the infinite loop might be because one thread may end up reading the value of the flag from its registers or cache instead of going to memory. As a result, it may never see the change made by the another thread to this flag.
Essentially by adding volatile you make the thread owning done flag to not cache this flag. Thus, the boolean value is stored in common memory and therefore guarantees visibility. Also, by using volatile you disabling JIT optimization that can inline the flag value.
Basically if you want to reproduce infinite loop - just run your program in server mode:
java -server VolatileTest
The default, non-volatile, implicit declaration of all Java values allows the Jit compiler to "hoist" references to non-volatile values, out of loops so that they are only read 'once'. This is allowed after a tracing of execution paths can safely arrive at the fact that the methods called inside of such a loop, don't ever cause entry back into the classes methods where it might mutate the value of these non-volatile values.
The System.out.println() invocation goes to native code which keeps the JIT from resolving that 'done' is never modified. Thus the hoist does not happen when the System.out.println() is there and as you found out, the infinite loop is only happening with it removed where the JIT can resolve that there is no write to 'done'.
The ultimate problem is that this reference hoisting is conditional on "reachability" of a mutation of the value. Thus, you may have moments where there is no reach to a mutation of the value, during development, and thus the hoist happens and suddenly you can't exit the loop. A later change to the loop might use some function that makes it impossible to discern that the value cannot be written by the logic in the loop, and the hoist disappears and the loop works again.
This hoist is a big problem for many people who don't see it coming. There is a pretty large group of belief now that safe Java has class level variables either declared as volatile or final. If you really need a variable to be "optimizable", then don't use a class level variable and instead make it a parameter, or copy it into a local variable for the optimizer to go after. Doing this with read only access helps manage "dynamic" changes in a value that disrupt predictable execution paths too.
There is has been recurring discussion on the java concurrency mailing list about this issue. They don't seem to believe that this is a problem for Java developers and that this "optimization" of reference is far more valuable to performance than problematic to development.

Java: how to avoid method being called twice in loop

This is my situation:
I have a loop,
inside that loop I need to verify a condition
if the condition is verified call 2 methods (the methods need to be called only once)
Since the application is having strange behaviors I suspect the loop is too fast, and the methods might be called more than once
Please how to avoid this??
#Override
public void loop() {
Thread.sleep(1000);
if (thisIsTrue()) { //Condition checked
setThisFalse(); //Set the condition above false
thanDoSomethingElse(); //Method to executed ONLY ONCE
}
}
Since this is tagged as concurrency, I suggest introducing a synchronized block:
private Object conditionSync = new Object();
#Override
public void loop() {
Thread.sleep(1000);
synchronized(conditionSync) {
if (thisIsTrue()) { //Condition checked
setThisFalse(); //Set the condition above false
thanDoSomethingElse(); //Method to executed ONLY ONCE
}
}
}
However, make sure that all methods that access or modify the variable used in thisIsTrue() and setThisFalse() also access it in a synchronized way. It might be better to redesign the application and introduce a single method that checks and modifies the variable.
Another option is the use of AtomicBoolean.compareAndSet() [Oracle]
I hope by strange behaviors you mean sometimes there is no problem while at other times there are random changes in state which are not reproducible.
If yes then most likely you are having problems related to multiple threads modifying state at same time. In such situation the final outcome depends on timing of operations which is not predictable.
You can synchronize the access to the variable 'thisIsTrue' method is evaluating and make sure that checking the value and modifying the value happen atomically. If you are not familiar with synchronization constructs, you can go through oracle's tutorials on java synchronization.
You can guard your method call with an AtomicBoolean.
Here is a sample code:
final AtomicBoolean executed = new AtomicBoolean(false);
// this is not a variable defined in a method. If your code will be called by
// multiple threads, those threads must have access to this variable.
if (executed.compareAndSet(false, true)) {
// call your method here. It is guaranteed to be called only once.
}
If number of threads that concurrently call your method is high, this may perform poorly.

multithreading beginner question

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

Simple thread problem in java

Works except for when I free the crawler:
public void setCrawlerFree(WebCrawler w)
{
synchronized(myFreeCrawlers)
{
synchronized(numToGo)
{
myFreeCrawlers.add(w);
myFreeCrawlers.notifyAll();
numToGo--;
numToGo.notify();
}
}
}
When the crawler is done, I can add it back on the list. I also want to subtract 1 from the number of things I still need to do. I have one main thread waiting until numToGo is at 0. I'm getting an IllegalMonitorStateException on numToGo.notify() but since its inside of the synchronization block, doesn't that mean I own it?
Consider rewriting it to ExecutorService.
ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize,
maximumPoolSize, keepAliveTime, timeUnit,
new LinkedBlockingQueue<Runnable>());
executor.submit(new Callable<...>() { ... });
It would greatly simplify your code and eliminate thread synchronization issues.
So I thought I needed to call wait and
notify on the object that all the
threads have in common, but that's not
correct either.
Yes, it is. But:
public class IllegalMonitorStateException
extends RuntimeException
Thrown to indicate that a thread has
attempted to wait on an object's
monitor or to notify other threads
waiting on an object's monitor without
owning the specified monitor.
You need to synchronize on an object before calling wait() or notify() on it.
Is your numToGo field is a primitive type which is being wrapped ? (int to Integer, long to Long, etc). Remember these wrappers are immutable and will cause you to have different object every time the boxing/unboxing happens. It's always recommended to use final objects when synchronization is needed.
Instead of using and integer create your own object to maintain the value and synchronization.
class Counter {
private int value ;
private final Object lock = new Object() ;
public ExecutionStatus() { }
public void increment() {
synchronized(lock) {
value ++ ;
}
}
public void decrease() {
synchronized(lock) {
value-- ;
}
}
// Read dirty
public int count() {
return value ;
}
public int safeCount() {
synchronize(lock) {
return count() ;
}
}
}
Never the less, you can add the line private final Object lock = new Object() to your current code and use that to control the synchronization of the numToGo variable.
Hope this helps.
you are synchronising on a non-final member variable. Your sync(numToGo) syncs on some value of numToGo and then you change the reference: numToGo--. You now have a different instance on which you call notify, hence the exception.
Some good posts there, there are plenty of alternatives but I imagine this is some kind of academic exercise? As people have pointed out, you'd probably wouldn't use wait/notify/notifyAll when there are more modern alternatives that makes things easier. The wait/notify thing though is interesting and is well worth understanding as a basis for concurrency work.
I'm assuming this is some kind of consumer/producer thing? One thread is trapping a crawler, the other setting it free? If that's the case, you might want to wait for the trap to have occupants before setting free? it might look something like this...
private final List<Object> trap = new ArrayList<Object>();
public class BugCatcher {
public void trapCrawler(Object crawler) {
synchronized (trap) {
trap.add(crawler);
System.out.println("caught bug number " + trap.size() + "!");
trap.notifyAll();
}
}
}
public class Hippy {
public void setCrawlerFree(Object crawler) throws InterruptedException {
synchronized (trap) {
trap.wait();
trap.clear();
System.out.println("set bugs free! time to hug a tree");
}
}
}
If the BugCatcher can catch bugs quicker than the hippy releases them, the hippy waits for the trap to have something in it before attempting to release the bugs (hence the wait call).
If you leave out the wait/notify part, things will rely just on the synchronized keyword, only one thread will access the trap at a time and its a race as to which gets there first (the hippy might try an empty an already empty trap).
In order to co-ordinate the wait and notify, the VM will use an object monitor. A thread acquires the object's monitor when it enters a synchronized block. An object has just a single monitor which acts as a mutually exclusivity lock (mutex). If you try and wait or notify without first getting the object's monitor (without executing wait or notify within a synchronized block), the VM can't set things up and so throws the IllegalMonitorException. It's saying "I can't allow this because if, for example, I wait, when will I know that I can progress when somebody calls notify? what/who are they notifying?". It uses the monitor to coordinate and so forces you to acquire the monitor.
So, the error you get is because numToGo isn't syncrhonised in the other thread (as Michael said previously).
I can't quite see why you need the numToGo, if it is producer/consumer, do you want to stop after a certain number? After the bug catcher catches 10 bugs and the hippy releases 10? Doesn't sound like that's what you're trying to do (as they could both have unrelated internal counters), so I'm not sure what you trying to do there. It'd be good to outline what you're trying to do in case I've gone off on completely the wrong tangent!

Categories