Java Thread - Is this proper use of synchronized - java

I am using the Bluetooth on Android; the short of it is that I only want to open a new Thread for receiving if the socket is currently not connected - I am testing this using a boolean.
So:
class Main {
protected boolean mConnected;
public void startClientConnection() {
ClientRunnable thread = new ClientRunnable() {
#Override public void manageSocket(BluetoothSocket pSocket) {
synchronized (this) {
if (!mConnected) openReadingThread(pSocket);
} // end synchronized()
} // end manageSocket()
}; // end ClientRunnable
} // end startClientConnection()
} // End CLASS
Edited:
Essentially, what I need to know is, because the Runnable will be run on a separate Thread, but the mConnected variable will only changed in the main Thread, does it need to be synchronized.

in this case, each thread you create has its own lock (the object itself)
you should use something static (like a class) for the lock.

The simple answer: mConnected must be accessed only within a synchronized block. The code you show is good, but the code where you change the value must also be in a synch block. The reason for this is that otherwize Java is under no obligation to let one thread see changes made by the other. In this case, you don't really need the synch blocks to synchronize anything, just to force each thread to see the other's changes.
Less simple: This is almost a good case for making mConnected volatile. You could then skip the synchronized block. But then it would be possible to get two threads in openReadingThread at the same time.
So keep the synch block in your example (which is more for openReadingThread than for mConnected), and either use another when you set mConnected or make mConnected volatile. Volatile fields are expensive, but then so are synch blocks, particularly when you don't need to synchronize but only make a field visible across threads. I'd say if changes are few and you go through the code above a lot, skip the volatile and use a second synch block. But if you change the value a lot, go with a volatile mConnected and only one synch block (the one in your example, which is now needed only for the method, not for mConnected).
Addtional: I was about to tell Philipp Sander that he was wrong about the "this" but, on second glance, he's not; it needs fixing.

Related

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.

Why to use wait method on strings or other objects?

I have following piece of code:
synchronized void myMethod() {
String s="aaa";
try {
s.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
The code throws exception ...
I have seen codes using wait method on threads which is self explainable and logical..
why would one use wait method on an object like string instead of using it on main thread?
what is its use?
are there any practical implementations like this?
Thanks in advance
Your sample code won't work because the method is synchronizing on the instance that myMethod is called on, while the wait is called on the string. It will cause an IllegalMonitorStateException. You have to call wait and notify on the same object that you're locking on. The threads that get notified are the ones waiting on the lock that notify is called on.
Locking on a string object is a bad idea, don't do it. You don't want to lock on things where you can't reason about who can acquire them because anybody could acquire them. Some other code elsewhere in the application could be locking on the same string value, and you'd have the potential for strange interactions, deadlocking because the other code was taking your lock, or have the other code notifying you. Do you want to have to think about how strings are pooled when debugging some multithreading behavior?
You can limit who can acquire your lock by defining your own lock and making it private, like this:
private final Object LOCK = new Object();
so only threads calling the methods of the object you're controlling access to can acquire the lock:
public void myMethod() {
synchronized(LOCK) {
...
}
}
That way you know exactly what can acquire the lock, it's not available to every thread in the application. The lock can be acquired by anything that can get a reference to that object, so keep the reference private.
The way your example uses wait without a loop with a condition variable is very suspect. A thread can exit from a call to wait without having been notified. Even if a thread is notified, that doesn't give it any special priority with the scheduler. Another thread can barge in and do something, possibly something affecting the state that the notification was alerting the waiting thread to, between the time the thread is notified and the time that the thread can reacquire the lock it gave up when it started waiting. For both reasons there needs to be a loop where the thread retests a condition when it wakes from waiting.
Also if by "codes using wait method on threads" you mean code where a Thread object is used as a lock, that's another thing to avoid doing, see the API documentation for Thread#join:
This implementation uses a loop of this.wait calls conditioned on this.isAlive. As a thread terminates the this.notifyAll method is invoked. It is recommended that applications not use wait, notify, or notifyAll on Thread instances.
You first need to be synchronized on the Object before calling wait. This is where you are getting the exception from.
void test() {
String s = "AAA";
synchronized( s ) {
s.wait();
}
}
The same thing must be done when you call notify, but in this case it is a very very bad idea because if a thread enters this method it will never return. Although considering it is a String literal you may be able to get away with it by using the same literal in another method in the same class, but don't count on it.
wait() method is implemented in Object, and String extends object so it can be used.
why someone use it? ask him. its not a programming question.
something i can think of:
he could be using "lock1".wait() in one class and "lock1".notify() in other, it will be something like global lock object
because literals are interned by
the compiler and thus refer to the same object
but its VERY VERY BAD PRACTICE
This is an example of synchronization with no affect.
First of all, it is unlikely you will need to synchronize on String, it is immutable after all, therefore, you don't need it to perform anything asynchronously.
Second, you are likely to be synchronizing on the incorrect object anyways, no correctly written program would use String as a synchronization lock.
Third and finally, s is a local variable. In fact, it holds exactly the same pattern that JCIP specifically tells you not to use if you inline it:
synchronized (new Object()) {
// ...
}
This is synchronization without effect, as it does not guarantee the purpose of the synchronized keyword: serialized access, lock and release semantics that require that only one thread execute the synchronized block at any given time.
Because of this, each thread will have their own lock - not good.

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.

Why could this code fail?

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.

Categories

Resources