If I have several mutable properties in an object that will be acted upon by several threads, I understand they should be synchronized.
class Doggie {
private String name;
private int age;
public void setName(String name) { this.name = name; }
public String getName() { return this.name; }
public void setAge(int age) { this.age = age; }
public int getAge() { return this.age; }
}
Questions:
Are not return and assignment atomic operations in Java?
Since properties might not necessarily be interrelated, it does not always make sense to synchronize with the same lock. How to organize the locking structure?
Is it better to go with the intrinsic lock or a private Object lock pattern?
Are not return and assignment atomic operations in Java?
Yes they are atomic (in some cases at least), but atomicity is not the only issue. Another important issue is whether the action of a write to an attribute by one thread is guaranteed to be visible to a following read for the same attribute made by a different thread.
When the reads and writes are in the same thread, the read is guaranteed to see the earlier write.
When the reads and writes are in different threads, the read is only guaranteed to see the earlier write if the two threads synchronize properly ... or if the attribute is declared as volatile.
Note that primitive locks/mutexes are not the only way to synchronize.
Since properties might not necessarily be interrelated, it does not always make sense to synchronize with the same lock. How to organize the locking structure?
It makes sense to use multiple locks if (and only if) lock contention is likely. In your example, lock contention is only likely to be an issue if some Doggie instance receives a very high rate of get and/or set operations.
Is it better to go with the intrinsic lock or a private Object lock pattern?
It depends. If your application is going use the Doggie object's primitive lock, then you might get lock contention or even unintended locking out of get and set operations. In that case a private lock might be advisable. Otherwise, a private lock is an unnecessary overhead.
Your example begs for an immutable object. http://java.sun.com/docs/books/tutorial/essential/concurrency/imstrat.html
Operations with references are atomic, but not volatile - you will always see the old value or the new value, but there's no guarantee you'll see the new value without some sort of memory barrier. I can't remember the details of which primitives are guaranteed to be atomic - probably all but long and double.
Personally I'd use a single private lock until I saw any evidence that it was a bottleneck. I would advise against locking on "this" as other code might lock on it too. If you're the only code that knows about the lock, it's harder to get interference. Having said that, if callers want to atomically change more than one property, you may want to expose the lock via a property.
Do you definitely need a threadsafe mutable type? If you could avoid that requirement it would make life simpler.
They are atomic operations, but picture a scenario where two clients are trying to get and set a piece of data at the same time. There is no guarantee as to which order things are going to be called which could greatly affect the results of your application. (The classic example is money transactions.)
It may or may not make sense to synchronize with the same lock - that really depends on your application. However, it typically is not a good idea to lock the entire object out if it is not necessary.
As with what Jon said, start with a single, private lock and go from there depending on results.
You're right to take note that non-interrelated properties can have different locks. Considering that locking objects require trivial memory, I would personally go with a lock per property instead of one for the entire object.
The lightweight way to do this is just to have a boolean that's set while the property is being written to and clear otherwise. The heavyweight way to do this, to support timeouts etc., is with a mutex.
Related
Assuming the following class:
public class Counter {
private long val;
private final ReadWriteLock reentrantLock = new ReentrantReadWriteLock();
public Counter(long val) {
this.val = val;
}
public void increment() {
try {
reentrantLock.writeLock().lock();
val++;
} finally {
reentrantLock.writeLock().unlock();
}
}
public long getVal() {
try {
reentrantLock.readLock().lock();
return this.val;
} finally {
reentrantLock.readLock().unlock();
}
}
}
Ignoring that we could use AtomicLong, what bad things could happen when we read without a lock and why are these things happening.
My assumptions:
Not the latest value (a new writer thread could update the value +1 in the moment we read), so we would be at least one value behind
Some garbage in-between writes value (can that happen in java)
Another assumption:
There's no risk of not seeing any writer value, since the WriteLock enforces memory barriers which will flush the value to main memory
Anything I'm missing?
The bad thing that can (in theory) happen is if readers don't use the read locks is that they could see a stale value of the counter; i.e. a value that is NOT the latest value written by a writer.
In Java, primitive locks and Lock classes have two functions:
The provide mutual exclusion.
They provide threads with certain guarantees about visibility of values in shared variables.
Without the visibility guarantees provided by correct use of locks (and some other things), changes made by one thread may not be visible to another thread.
Unfortunately, while there is no guarantee that that one thread won't see the correct value, there is no guarantee that it will see an incorrect one either. The actual behavior depends on a number of different factors that are difficult to analyze ... and are implementation and platform dependent. So demonstrating that a thread can see stale values can be difficult. Likewise, you cannot prove that a program doesn't have that kind of flaw by testing it. And if a program does have this kind of flaw, it is likely to be hard to reproduce ... especially when you are using a debugger.
Not the latest value (a new writer thread could update the value +1 in the moment we read), so we would be at least one value behind.
In fact, the reader could see a value that many updates behind ... or even the initial value of val.
Some garbage in-between writes value (can that happen in java)
This is also possible. The JMM treats a long or a double as two separate memory cells, so an reader that doesn't use locks could see a high word from one value and a low word from a different value.
There's no risk of not seeing any writer value, since the WriteLock enforces memory barriers which will flush the value to main memory.
This is incorrect from two respects:
That is an implementation detail. The JMM says nothing about memory barriers, and neither do the relevant javadocs.
In fact if the reader is not using a read lock, the JIT compiler might emit code that caches the value of val in a register ... and not bother to re-read it from main memory in all circumstances.
Note that this is also an implementation detail. But this is a behavior that is permitted by the JMM. When the reader doesn't use the lock, there will be no happens before relation between the write and the subsequent read. With out that relation, the code doesn't need to meet the visibility guarantee.
I am creating Socket based Server-Client reservation service, and have problem about class which will be accessed by multiple threads, does it need to Extend ConcurrentHashMap or is it enough to create variable ConcurrentHashMap to be thread safe?
I have two ideas but I am not sure if first one will work, so the first one would be creating class which only implements Serializable has variable date and then variable ConcurrentHashMap on which threads want to operate, second idea is to have class which extends Concurrent Hash Map and just is CHP but with addiontal variable to make sure it is distinguishable from others
public class Day implements Serializable {
private LocalDate date;
private ConcurrentHashMap<String, Boolean> schedule;
public Day(LocalDate date){
this.date = date;
this.schedule = new ConcurrentHashMap<>();
IntStream.range(10, 18).forEachOrdered(
n -> this.schedule.put(LocalTime.of(n, 0).toString(), TRUE));
}
public void changeaval(String key,Boolean status) {
this.schedule.replace(key,status);
}
public boolean aval(String key){
return this.schedule.get(key);
}
public LocalDate getDate(){return this.date;}
public ConcurrentHashMap getSchedule(){return this.schedule;}
}
I just want to have Class/Object which can be accessed by multiple threads and can be distinguishable from others/comparable and has ConcurrentHashMap which maps Int -> Boolean
This is the first time I am using Stack and It is my first project in Java so I don't know much sorry if something is not right.
There are basically two things to look out for when dealing with objects accessed by multiple threads:
Race condition - Due to thread scheduling by the operating system and instruction reordering optimizations by the compiler, the instructions are executed in a order not intended by the programmer causing bugs
Memory visibility - In a multi processor system, changes made by one processor is not always immediately visible to other processors. Processors keep things in their local registers and caches for performance reasons and therefore not visible to threads being executed by other processors.
Luckily we can handle both these situation using proper synchronizations.
Let's talk about this particular program.
Localdate by itself is an immutable and thread safe class. If we look at the source code of this class, we'd see that all the fields of this class are final. This means that as soon as the constructor of Localdate finishes initializing the object, the object itself will be visible across threads. But when it is assigned to a reference variable in a different object, whether the assignment (in other words, the content of the reference variable) would be visible to other threads or not is what we need to look out for.
Given the constructor in your case, we can ensure the visibility of the field date across threads provided date is either final or volatile. Since you are not modifying the date field in your class, you can very well make it final and that ensures safe initialization. If you later decide to have a setter method for this field (depending on your business logic and your design), you should make the field volatile instead of final. volatile creates a happens-before relationship which means that any instruction that is executed in the particular thread before writing to the volatile variable would be immediately visible to the other threads as soon as they read the same volatile variable.
Same goes for ConcurrentHashMap. You should make the field schedule final. Since ConcurrentHashMap by itself has all the necessary synchronizations in it, any value you set against a key would be visible to the other threads when they try to read it.
Note, however, that if you had some mutable objects as ConcurrentHashMap values instead of Boolean, you would have to design it in the same way as mentioned above.
Also, it may be good to know that there is a concept called piggy-backing which means that if one thread writes to all its fields and then writes to a volatile variable, everything written by the thread before writing to the volatile variable would be visible to the other threads, provided the other threads first read value of the volatile variable after it is written by the first thread. But when you do this you have to ensure very carefully the sequence of reading and writing and it is error prone. So, this is done when you want to squeeze out the last drop of performance from the piece of code which is rare. Favor safety, maintainability, readability before performance.
Finally, there is no race condition in the code. The only write that is happening is on the ConcurrentHashMap which is thread safe by itself.
Basically, both approaches are equivalent. From architectural point of view, making a variable inside dedicated class is preferred because of better control of which methods are accessible to the user. When extending, a user can access many methods of underlying ConcurrentHashMap and misuse them.
private double value;
public synchronized void setValue(double value) {
this.value = value;
}
public double getValue() {
return this.value;
}
In the above example is there any point in making the getter synchronized?
I think its best to cite Java Concurrency in Practice here:
It is a common mistake to assume that synchronization needs to be used only when writing to shared variables; this is simply not true.
For each mutable state variable that may be accessed by more than one
thread, all accesses to that variable must be performed with the same
lock held. In this case, we say that the variable is guarded by that
lock.
In the absence of synchronization, the compiler, processor, and runtime can do some downright weird things to the order in which operations appear to execute. Attempts to reason about the order in which memory actions "must" happen in insufflciently synchronized multithreaded programs will almost certainly be incorrect.
Normally, you don't have to be so careful with primitives, so if this would be an int or a boolean it might be that:
When a thread reads a variable without synchronization, it may see a
stale value, but at least it sees a value that was actually placed
there by some thread rather than some random value.
This, however, is not true for 64-bit operations, for instance on long or double if they are not declared volatile:
The Java Memory Model requires fetch and
store operations to be atomic, but for nonvolatile long and double
variables, the JVM is permitted to treat a 64-bit read or write as two
separate 32-bit operations. If the reads and writes occur in different
threads, it is therefore possible to read a nonvolatile long and get
back the high 32 bits of one value and the low 32 bits of another.
Thus, even if you don't care about stale values, it is not safe to use
shared mutable long and double variables in multithreaded programs
unless they are declared volatile or guarded by a lock.
Let me show you by example what is a legal way for a JIT to compile your code. You write:
while (myBean.getValue() > 1.0) {
// perform some action
Thread.sleep(1);
}
JIT compiles:
if (myBean.getValue() > 1.0)
while (true) {
// perform some action
Thread.sleep(1);
}
In just slightly different scenarios even the Java compiler could prouduce similar bytecode (it would only have to eliminate the possibility of dynamic dispatch to a different getValue). This is a textbook example of hoisting.
Why is this legal? The compiler has the right to assume that the result of myBean.getValue() can never change while executing above code. Without synchronized it is allowed to ignore any actions by other threads.
The reason here is to guard against any other thread updating the value when a thread is reading and thus avoid performing any action on stale value.
Here get method will acquire intrinsic lock on "this" and thus any other thread which might attempt to set/update using setter method will have to wait to acquire lock on "this" to enter the setter method which is already acquired by thread performing get.
This is why its recommended to follow the practice of using same lock when performing any operation on a mutable state.
Making the field volatile will work here as there are no compound statements.
It is important to note that synchronized methods use intrinsic lock which is "this". So get and set both being synchronized means any thread entering the method will have to acquire lock on this.
When performing non atomic 64 bit operations special consideration should be taken. Excerpts from Java Concurrency In Practice could be of help here to understand the situation -
"The Java Memory Model requires fetch and store operations to be atomic, but for non-volatile long and double variables, the JVM is permitted to treat a 64 bit read or write as two separate 32
bit operations. If the reads and writes occur in different threads, it is therefore possible to read a non-volatile long and get back the high 32 bits of one value and the low 32 bits of another. Thus, even if you don't care about stale values, it
is not safe to use shared mutable long and double variables in multi-threaded programs unless they are declared
volatile or guarded by a lock."
Maybe for someone this code looks awful, but it works very well.
private Double value;
public void setValue(Double value){
updateValue(value, true);
}
public Double getValue(){
return updateValue(value, false);
}
private double updateValue(Double value,boolean set){
synchronized(MyClass.class){
if(set)
this.value = value;
return value;
}
}
I have been searching the web for this, but have been unable to find any article that comes close to this, and I'm quite surprised by that. Maybe the wisdom is hidden somewhere that I have yet to find.
Suppose I have a class with 10 members of various types (for the sake of simplicity, let's say they are mixed of ints and Strings), and each one of them has its own accessor methods. Now, I want to make this class thread-safe. But, some of these data members don't necessarily interact with each other. For example the class Person below, has age and name and other properties.
public class Person {
private volatile int age;
private String name;
private volatile long blabla;
// ... and so on
public synchronized int getAge() {
return age;
}
public synchronized void setAge(int age) {
this.age = age;
}
// .. and so on for each data member
}
One thread may only need to read/write age, and other threads only need to modify name. Obviously, adding synchronized to each and every one of the accessor methods is a bad idea as it locks the entire instance of the object. A thread that's calling getAge() has to wait for another thread that's calling getName() even though age and name are two separate fields.
So, one obvious solution is to create a lock for each field (or add volatile to primitive types). However, this seems to be an overkill. If I have 10 data members, do I also need 10 locks? I'm wondering if there's another way of achieving this without excessive locking.
If you are concerned about synchronizing primitive types, this is an excellent use case for AtomicInteger etc... They are very fast and ensure thread-safety. For more info:
http://docs.oracle.com/javase/tutorial/essential/concurrency/atomicvars.html
First off, if you are talking about primitives (or immutable objects like String) then all you should need is to mark each of the fields volatile. Locks won't be necessary if all you are doing is getting and setting field values.
However, if your get/set methods do multiple operations and synchronized blocks are need, having a synchronized blocks per field seems like premature optimization to me. I think that synchronized methods on a small object like your Person is a perfectly appropriate way to accomplish this. Unless you have real reasons (i.e. profiler output), I would not try to make it more complicated. Certainly a lock per field is overkill in just about any situation.
It would make a difference if the method takes a long time. Then you would not want to lock the entire object and block the other accessors. Then it is a good time to have multiple locks -- each for separate calculation. But if your object truly is just trying to protect get/set then a synchronized method is fine.
Couple of other comments:
If you can get away with just volatile fields then you don't need any synchronized blocks.
If you have synchronized methods then you do not need to make your fields volatile.
If the name field should probably be marked as final if it is not being written to.
Out of the below two synchronization strategy, which one is optimized (as in processing and generated byte code) and also the scenario in which one should use one of them.
public synchronized void addName(String name)
{
lastName = name;
nameCount++;
nameList.add(name);
}
or
public void addName(String name) {
synchronized(this) {
lastName = name;
nameCount++;
nameList.add(name);
}
}
Also what is advisiable way to handle concurrency:
using java.util.concurrent package
using the above low level methods
using Job or UIJob API (if working in eclipse PDE environment)
Thanks
which one is optimized (as in processing and generated byte code)
According to this IBM DeveloperWorks Article Section 1, a synchronized method generates less bytecode when compared to a synchronized block. The article explains why.
Snippet from the article:
When the JVM executes a synchronized method, the executing thread identifies that the method's method_info structure has the ACC_SYNCHRONIZED flag set, then it automatically acquires the object's lock, calls the method, and releases the lock. If an exception occurs, the thread automatically releases the lock.
Synchronizing a method block, on the
other hand, bypasses the JVM's
built-in support for acquiring an
object's lock and exception handling
and requires that the functionality be
explicitly written in byte code. If
you read the byte code for a method
with a synchronized block, you will
see more than a dozen additional
operations to manage this
functionality. Listing 1 shows calls
to generate both a synchronized method
and a synchronized block:
Edited to address first comment
To give other SOers credit, here is a good discussion about why one would use a sync. block. I am sure you can find more interesting discussions if you search around :)
Is there an advantage to use a Synchronized Method instead of a Synchronized Block?
I personally have not had to use a sync. block to lock on another object other than this, but that is one use SOers point out about sync. blocks.
Your updated two pieces of code are semantically identical. However, using a synchronized block as in the second piece allows you more control, as you could synchronize on a different object or, indeed, not synchronize parts of the method that don't need to be.
Using java.util.concurrent is very much preferrable to using synchronization primitives wherever possible, since it allows you to work at a higher level of abstraction, and use code that was written by very skilled people and tested intensively.
If you're working in eclipse PDE, using its APIs is most likely preferrable, as it ties in with the rest of the platform.
This totally does not matter from any efficiency point of view.
The point of having blocks is you can specify your own lock. You can choose a lock that is encapsulated within the object, as opposed to using this, with the consequence that you have more control over who can acquire the lock (since you can make that lock inaccessible from outside your object).
If you use this as the lock (whether you put synchronized on the method or use the block), anything in your program can acquire the lock on your object, and it's much harder to reason about what your program is doing.
Restricting access to the lock buys you a massive gain in decidability, it's much more beneficial to have that kind of certainty than to shave off a bytecode somewhere.
I know this might be an example, but if you plan on writing such code - think again.
To me it looks like you are duplicating information, and you should not do that unless you see that you need to do performance changes to your code. (Which you almost never should do).
If you really need this to be code that run in several threads, I'd make the nameList into a synchronized list using Collections.synchronizedList.
The last name should be a getter and it could pick the last element in the list.
The nameCount should be the size of the list.
If you do stuff like you have done now, you must also synchronize the access to all of the places where the variables are referenced, and that would make the code a lot less readable and harder to maintain.
You could remove all locking:
class Names {
AtomicReference<Node> names = new AtomicReference<Node>();
public void addName(final String name) {
Node old = names.get();
while (!names.compareAndSet(old, new Node(old, name))) {
old = names.get();
}
}
public String getName() {
final Node node = names.get();
return (node == null) ? null : node.name;
}
static class Node {
final Node parent;
final String name;
Node(final Node parent, final String name) {
this.parent = parent;
this.name = name;
}
int count() {
int count = 0;
Node p = parent;
while (p != null) {
count++;
p = p.parent;
}
return count;
}
}
}
This is basically a Treiber stack implementation. You can get the size, the current name, and you can easily implement an Iterator (albeit reverse to the one in your example) over the contents. Alternative copy-on-write containers could be used as well, depending on your needs.
Impossible to say, since the two code snippets arent equivalent.
The difference (the lack of synchronization of the call to add) may be significant, it might not be. From what you've given us its impossible to say.