Say I have a class with 2 instance variables and the following methods (simplified for this question):
private final Object lock = new Object();
private boolean running;
public MyClass() {
synchronized(lock) {
running = false;
}
}
public void methodA() {
synchronized(lock) {
running = true;
}
}
public void methodB() {
synchronized(lock) {
if (!running) {
return;
}
}
}
I was looking at this code, and after reading about AtomicBoolean, I thought that one might fit here, especially after looking at the MyClass constructor and methodA. I wasn't too sure about methodB though.
Assuming these methods could get called by multiple threads, would the following be thread-safe?:
private AtomicBoolean running;
public MyClass() {
running = new AtomicBoolean(false);
}
public void methodA() {
running.set(true);
}
public void methodB() {
if (!running.get()) {
return;
}
}
Will running.get() be guaranteed to see an update via running.set(true) or running.set(false) from another thread?
In your example, a simple volatile boolean would be enough, since you only seem to be doing atomic operations. AtomicBoolean is useful if you need the methods such as compareAndSet.
So in answer to your question, yes, when using a volatile boolean or an AtomicBoolean, other threads will see the updates to the variable.
Generally speaking these code blocks are not equal for methodB, because reading volatile variable does not create synchronization order.
Imagine you have some other field int x = 42 in your class, that is updated in methodB:
public void methodB() {
if (!running.get()) {
return;
}
if (x < 50) x++; // just example
}
Then you have several threads that call methodB:
when using synchronized keyword, updates are safe and visible to all threads.
when using AtomicBoolean/volatile visibility is broken
If there is no such case with variable updates and the task is just to guarantee visibility between methodA - methodB sequence, then it's OK - AtomicBoolean is enough for that.
Yes. From the Javadoc of AtomicBoolean:
A {#code boolean} value that may be updated atomically.
This means that any update to AtomicBoolean is indivisible. So, I would consider such use of AtomicBoolean to be thread safe.
You should still consider making the declaration of AtomicBoolean final:
private final AtomicBoolean running;
Related
I have an object that is accessed from multiple threads. I want to implement it so that in order to access its setters and getters, the caller must first explicitly lock it before and then unlock it after finishing. I've though about using synchronized methods but it doesn't seem very straight-forward compared to java's more explicit locking APIs. This is my current stubbed implementation using ReentrantLock.
public class Data {
private ReentrantLock lock;
private int IntValue;
public Data() {
this.IntValue = 0;
this.lock = new ReentrantLock();
}
public void Lock() {
lock.lock();
}
public void Unlock() {
if (!lock.isLocked()) {
return;
}
//only the thread owning the lock can proceed to unlock
lock.lock();
int lockCount = lock.getHoldCount();
for (int i = 0; i < lockCount; i++) {
lock.unlock();
}
}
public void SetVal(int val) {
if (!lock.isLocked()) {
return;
}
lock.lock();
this.IntValue = val;
}
}
So if a thread wants to call SetVal(int val), it would first have to call Lock() and then call Unlock() when it's done. I've placed isLocked() checks in its setter/getter methods to enforce this rule. And I've added an additional lock call in unlock to make sure only the thread owning the lock can proceed to unlock (an unique feature of ReentrackLock). The object's setters/getters could be called many times before its Unlock() method is called. So in the Unlock() method I have to iterate through its HoldCount and unlock for each count.
I'm wondering if there is a more efficient and idiomatic way of achieving this?
If you are only using int value then can go for AtomicInteger
or make all your method synchronized that you want to prevent from race condition.
or if you want to support both synchronized and normal then you can pit a wrapper like collections.SynchronizedSet.Hope this will help.
You are running into the wrong direction with your approach. OOP paradigms state that all data should be kept and managed internally, what you do however is to externalize that control over the internal data by giving it to the caller.
A good design would try to hide the fact that locking is even necessary and do it internally to free the caller from such tasks. Especially because if you transfer the responsibility of proper locking to the caller, then every single caller could be a potential thread issue. If you lock internally however, there is only a single source of potential bugs, so if you encounter an issue you know where to look.
This is how you would do it properly regarding the OOP paradigm:
public class Data {
// protected so it is accessible to derived classes
// final so the lock object cannot be (accidentally) reassigned
// Lock (base class) so it is easier to change the implementation later
protected final Lock lock;
// clear naming
private int value;
public Data() {
// value is automatically initialized with 0
this.lock = new ReentrantLock();
}
// by convention the setter for ... is set...
public void setValue(final int value) {
this.lock.lock();
// absolutely use try/finally here, to ensure it is unlocked in all cases
try {
this.value = value;
} finally {
this.lock.unlock();
}
}
// by convention the getter for ... is get...
public int getValue() {
this.lock.lock();
try {
return this.value;
} finally {
this.lock.unlock();
}
}
}
Consider the following code implementing double check locking using the synchronized keyword in JAVA 8:
private static void redoHeavyInitialisation() {
if (needToReinitialise()) {
synchronized (MyClass.class) {
if (needToReinitialise()) {
doHeavyInitialisation();
}
}
}
}
The reason double check locking is used is because the initialisation is heavy (hence lazy) AND it can happen more than once (hence singleton pattern can not be used, correct me if I am wrong).
Anyway, first, how do you convert the code above to use Lock from the JAVA concurrent package instead of using synchronized keyword?
Only after that AND optionally, feel free to comment on using Lock or synchronized keyword which one is better.
Remember, this question is not about Lock vs synchronized comparison. Answer attempts without answering the code conversion part will not be picked as accepted answer.
Transformation of synchronized blocks to the equivalent block using ReentrantLock is pretty rote.
First you create a lock with the same or similar scope and lifetime as the object you were locking on. Here you are locking on MyClass.class, hence a static lock, so you can map this to a static lock in MyClass, such as MyClass.initLock.
Then just replace each:
synchronized (object) {
with
lock.lock();
try {
and each associated closing brace with
} finally {
lock.unlock();
}
Putting it all together you have:
private final static ReentrantLock initLock = new ReentrantLock();
private static void redoHeavyInitialisation() {
if (needToReinitialise()) {
MyClass.initLock.lock();
try {
if (needToReinitialise()) {
doHeavyInitialisation();
}
} finally {
MyClass.initLock.unlock();
}
}
}
Performance-wise there is little daylight between the approaches. They essentially have the same semantics and usually use similar underlying mechanisms. In the past, there have been performance differences - sometimes optimizations have gone in that affect one or the other, so on some JVMs you can find a difference, but the whole point of double checked locking is to avoid taking the lock anyway, so just do what's simplest. You only get the lock for a very small transitory period while the needToReinitialise() method is running, so the locking cost won't have any ongoing impact.
Consider the following code:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class HeavyInitializer {
static final Logger logger = LoggerFactory.getLogger(HeavyInitializer.class);
static HeavyInitializer singleton;
public static synchronized HeavyInitializer getInstance() {
if (singleton==null) {
singleton = new HeavyInitializer();
}
return singleton;
}
boolean initialized;
private HeavyInitializer() {
initialized = false;
}
public synchronized void initialize() {
if (!initialized) {
heavyStuffDoneHere();
}
}
public synchronized void reInitilize() {
if (needToReinitialise()) {
heavyStuffDoneHere();
}
}
private void heavyStuffDoneHere() {
initialized = true;
}
private boolean needToReinitialise() {
if (!initialized)
return false;
boolean ret = false;
//Do your check here... and set ret
return ret;
}
}
From Oracle's doc:
... then making these methods synchronized has two effects:
First, it is not possible for two invocations of synchronized methods on the same object to interleave. When one thread is executing a synchronized method for an object, all other threads that invoke synchronized methods for the same object block (suspend execution) until the first thread is done with the object.
Second, when a synchronized method exits, it automatically establishes a happens-before relationship with any subsequent invocation of a synchronized method for the same object. This guarantees that changes to the state of the object are visible to all threads.
Trying to use Lock would be trying to reimplement the synchronized block. Not necessary.
Singleton Double checks the lock and prevents singleton object to break using serialization.
package pattern.core.java;
import java.io.Serializable;
public class Singleton extends Object implements Serializable {
private static final long serialVersionUID = 1L;
private static Singleton sg;
private Singleton() {
}
public static Singleton getSingletonObj() {
if (sg == null) {
synchronized (sg) {
if (sg == null) {
sg = new Singleton();
}
}
}
return sg;
}
/*
* this method ensures that new object will not be created for singleton
* class using serialization and deserialization
*/
protected Object readResolve() {
return sg;
}
/*
* #Override protected Object clone() throws CloneNotSupportedException {
* throw new CloneNotSupportedException(); }
*/
#Override
protected Object clone() throws CloneNotSupportedException {
return sg;
}
}
I am writing a utility class to implement the behavior of a stopwatch. One important feature of this class is that it is designed to be thread-safe. I use a private final field called lock to synchronize on. Two of the methods in the class are called reset and start, which reset the stopwatch and start it, respectively. They are implemented as:
public void reset() {
synchronized (lock) {
beginTime = 0;
lapIndex = 0;
}
}
public void start() {
synchronized (lock) {
if (beginTime == 0) {
beginTime = System.nanoTime();
laps[lapIndex++] = beginTime;
}
}
}
Recently, I had the idea of adding an additional convenience method called restart, which would reset and the start the stopwatch. I want this to behave like an atomic operation, so my idea was to implement it as:
public void restart() {
synchronized(lock) {
reset();
start();
}
}
However, the reset and start methods already synchronize on lock, so invoking restart would synchronize on the same object two times. Could any problems arise from that? Is the behavior of synchronizing on the same object multiple times well-defined? Is it necessary? I have ran the code as it seems to work fine, but I fear I could be missing some subtleties as is common with multithreading.
There's no problem with synchronizing twice. The thread already owns the monitor so the extra synchronization doesn't really do much. This will be necessary, otherwise your restart() method might be interrupted by another thread between calls to reset() and start().
A way of avoiding the double synchronization is to have restart(), reset(), and start() synchronize and then delegate to non-synchronized internal methods.
public void reset() {
synchronized (lock) {
_reset();
}
}
public void start() {
synchronized (lock) {
_start();
}
}
public void restart() {
synchronized(lock) {
_reset();
_start();
}
}
private void _reset() {
beginTime = 0;
lapIndex = 0;
}
private void _start() {
if (beginTime == 0) {
beginTime = System.nanoTime();
laps[lapIndex++] = beginTime;
}
}
From section 14.19 on synchronized statements of the Java language specification:
The locks acquired by synchronized statements are the same as the locks that are acquired implicitly by synchronized methods (ยง8.4.3.6). A single thread may acquire a lock more than once.
Also from the JLS:
A thread t may lock a particular monitor multiple times; each unlock reverses the effect of one lock operation.
Therefore, this shouldn't be a problem.
How can I access static variable from many thread simultaneously.
If I have a class like
Class A {
public static boolean FLG=false;
.....................
....................
}
And I need to access the value from thread 1 like
....................
public void run() {
boolean t1=A.FLG;
..................
}
and from thread 2 I need to set value like
....................
public void run() {
A.FLG=true;
..................
}
Does this cause memory violation ?. If so what is the recommended method to handle such a situation?.
If all you want to do is get and set a primitive you can make it volatile and it will be thread safe for those operations.
Wrap the static variable in a synchronized method and call the method as you like
public static synchronized void method1(){
//Whatever
}
public static synchronized void method2(){
//Whatever again
}
Note that there are other ways to synchronize access to a method. They are considered more efficient in environments busy threads accessing the same methods.
Check the ReentrantLock class. There are also answers for when to use synchronized and RentrantLock and many more information that could be found through google.
Also as peter's answer and muel's comment suggests. Marking the boolean variable as volatile should be helpful. volatile boolean variables will NOT cache it's initial value (false or true). The JVM could do that occasionally which could be unexpected by the programmer.
You may get some undesired situation where two threads try to set different values into the static variable and you won`t have sure what exactly value really is there. The best way (thinking in a simple scenario) I think it is using AtomicBoolean ( http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/atomic/AtomicBoolean.html ) and you get the value in the object and use it (instead of using the object all the time, due a different thread can change it and you might get unexpected scenario).
Another suggestion is to use Byteman to create concurrent tests.
Regards,
Luan
In Class A , you can create a set and get method for FLG like:
public static synchronized boolean getFlag()
{
return FLG;
}
public static synchronized setFlag(boolean flag)
{
FLG=flag;
}
Now from other Threads, access value of FLG usng this method. This will keep the value of FLG Consistent across multiple Threads.
If you do not want to use synchronized, ReentrantLock,
you can write your own logic for this.
Example:
public class A extends Thread{
public static boolean FLG=false;
public A(String threadName) {
start();
setName(threadName);
}
#Override
public void run() {
// TODO Auto-generated method stub
while(true){
if(this.getName().equals("getterThread") && FLG == true){
boolean t1=A.FLG;
}
if(this.getName().equals("setterThread") && FLG == false){
A.FLG = true;
}
}
}
public static void main(String[] args) {
A dad = new A("getterThread");
A son = new A("setterThread");
}
}
I have some code that I want to have some one time initialisation performed. But this code doesn't have a definite lifecycle, so my logic can be potentially invoked by multiple threads before my initialisation is done. So, I want to basically ensure that my logic code "waits" until initialisation is done.
This is my first cut.
public class MyClass {
private static final AtomicBoolean initialised = new AtomicBoolean(false);
public void initialise() {
synchronized(initialised) {
initStuff();
initialised.getAndSet(true);
initialised.notifyAll();
}
}
public void doStuff() {
synchronized(initialised) {
if (!initialised.get()) {
try {
initialised.wait();
} catch (InterruptedException ex) {
throw new RuntimeException("Uh oh!", ex);
}
}
}
doOtherStuff();
}
}
I basically want to make sure this is going to do what I think it's going to do -- block doStuff until the initialised is true, and that I'm not missing a race condition where doStuff might get stuck on a Object.wait() that will never arrive.
Edit:
I have no control over the threads. And I want to be able to control when all of the initialisation is done, which is why doStuff() can't call initialise().
I used an AtomicBoolean as it was a combination of a value holder, and an object I could synchronize. I could have also simply had a "public static final Object lock = new Object();" and a simple boolean flag. AtomicBoolean conveniently gave me both. A Boolean can not be modified.
The CountDownLatch is exactly what I was looking for. I also considered using a Sempahore with 0 permits. But the CountDownLatch is perfect for just this task.
That's a strange mix of library and built-in concurrency controls. Something like this is much cleaner:
public class MyClass {
private static final CountDownLatch latch = new CountDownLatch(1);
public void initialise() {
initStuff();
latch.countDown();
}
public void doStuff() {
try {
latch.await();
} catch (InterruptedException ex) {
throw new RuntimeException("Uh oh!", ex);
}
doOtherStuff();
}
}
A synchronized block will automatically block other threads. Just use a simple lock object + status variable:
public class MyClass {
private static boolean initialised;
private static final Object lockObject = new Object();
public void initialise() {
synchronized (lockObject) {
if (!initialised) {
initStuff();
initialised = true;
}
}
}
public void doStuff() {
initialise();
doOtherStuff();
}
}
The best may be to use a static initializer (as mentioned by SB):
public class MyClass {
public static void doInitialize() {
...
}
public void doStuff() {
doOtherStuff();
}
static {
doInitialize();
}
}
This will get executed once before any other code is allowed to be called. If you will always have to initialize anytime the class is used then there is no performance hit as the class will not be loaded until it is used. See the answers to this question for more details.
It this is right at startup, why not wait to start the other threads until the initialization is complete?
Also, you can do a thread-synchronized IsComplete boolean that is set to false until it is set to true by the initialization routine.
You're using AtomicBoolean always from inside a synchronized block. There's not much point to that since only one thread can access it. Atomic variables are intended for use in lock-free solutions - you can get and set the value as an uninterruptable unit.
I guess you are looking for a lock free solution once the intiialization has happened:
public class MyClass {
private static final AtomicBoolean initialised = new AtomicBoolean(false);
public void initialise() {
if (!intialized.get())
{
synchornized (this)
{
if (!initialized.getAndSet(true))
doInitialize();
}
}
}
public void doStuff() {
initialize();
doOtherStuff();
}
You could also do this with a simple volatile boolean which is actually a little more efficient than an AtomicBoolean.