Locking on a mutable object - Why is it considered a bad practice? - java

See this answer. It says:
Six really bad examples;
...
locking on a mutable field. e.g. synchronized(object) { object = ...; }
What's wrong with locking on a mutable field? What if object was declared as final but was not an immutable class?

It is a bad idea because if another thread changes the reference in the critical section, the threads will no longer see the same reference, and so they will not synchronize on the same object, thus running uncontrolled. Example:
synchronized(lock1) {
lock1 = new Object();
sharedVariable++;
}
Assume 2 threads are trying to enter this critical section. Thread 1 enters and thread 2 waits. Thread 1 goes in, reassigns lock1 and proceeds. Now thread 2 sees a different lock than what thread 1 acquired, which is also free, so it can also enter the critical section. Fun ensues!
If the object is final, you cannot reassign the reference to a different object, so the above problem no longer applies.

"Mutable" isn't the right word here. It's okay to lock on a mutable object, i.e. an object with state. What's wrong is to lock on a field, change it, and expect another thread to lock on the same object.

I don't think locking a mutable object is bad in itself. It is just very hard to get it right. There are other models for concurrent processing, like actors. I suggest you look into Akka, which can be used from both Java and Scala, and is a very solid implementation.

Related

Using the lock of synchronize block

if I have variable Integer[] arr = new Integer[5] and i use one of the cells as synchronize block lock - can I use it inside the block?
synchronize(arr[index])
{
arr[index]++;
}
If the answer is yes - so what exactly the lock means? what the program do to this lock while synchronization?
another question - does it lock only the cell or all of the array?
In other words - Does another Thread can use the arr[index+1] in the block in parallel?
Thanks!
1) .... can I use it inside the block?
Yes
2) If the answer is yes - so what exactly the lock means? what the program do to this lock while synchronization?
What it means is that some other thread that attempts to synchronize on the same object will be blocked until "this code" releases the lock on the object.
There are also memory coherency effects. If you synchronize (properly) one thread is guaranteed to see changes made by another one.
3) another question - does it lock only the cell or all of the array?
Neither. It locks on the object (the Integer instance) that the array cell refers to.
Also the lock applies only to other threads that attempt to synchronize on the same object. If another thread attempts to synchronize on a different object, or if it attempts to access the object without synchronizing, then it is not blocked.
4) In other words - Can another thread use the arr[index+1] in the block in parallel?
It depends on precisely what the other thread does. See above.
Aside: Your example is rather odd. An Integer object is immutable, so there seems little point in synchronizing on it. This may be just a contrived example, but if not, then you most likely have a problem in your application design. Unfortunately, the example offers us no clues to understand what you are really trying to do here.
But the simple lessons are:
you synchronize on objects, not array elements, or variables
synchronization only works if all threads synchronize when using a shared object.
It locks the object (Integer) that happens to be at position index in the array at the beginning of the synchronized block. Which is not very useful in the case of Integers, because the statement arr[index]++ will replace the object with another (unlocked) one.
UPDATE
It doesn't lock anything useful, neither the full array, not the cell at position index. Besides, Integer objects (that are immutable) can be kept in a cache to be reused as a result of valueOf(). You may also get a NullPointerException if the array is not initialized.
In summary: don't do that.

Threads and Synchronization

I have a little difficulty in understanding the concept of private locks:
public class MyObject {
private final Object lock = new Object(); // private final lock object
public void mymethod() {
synchronized (lock) { // Locks on the private Object
// ...
}
}
}
In the code above, lock is acquired on a different object but the code in the current object is guarded by synchronised block. Now, apart from the lock object in the code above, it could be any other object too. I find it difficult to understand how the lock on another object is related to the synchronised keyword in the current object. IMO, it may lead to some malicious code to lock any object. What is the basis of allowing locks on other objects.
Well you could, for example, have an object that manages two lists.
If its possible for thread A to alter list 1 while thread B alters list 2 then you'd use distinct locks, rather than synchronizing on the owning object.
Essentially explicit locks allow for finer grained control of behavior.
IMO, it may lead to some malicious code to lock any object.
This is the crux of the issue, actually.
With a separate lock object as shown (crucially, with private access) then only code in the MyObject class will be able to acquire a lock on that monitor - so you can see all of the code that might take part in locking situations involving this class.
Going to the other extreme, if you acquire a lock on e.g. a constant String, then any code, anywhere in the same JVM that locks on the same String will contend with your class - which is almost certainly not intended and will be very hard to track down.
Basically - if you lock on a non-private object, that then becomes part of your public interface, effectively. Sometimes this is intended (e.g. for the Collections.synchronizedFoo objects, they declare that one can synchronize on the object itself in order to coarsen your lock). Often it is not and is merely an oversight.
You should keep your lock monitors private, for the same reason you keep private member variables private - to prevent other code messing with things that they shouldn't. And this is basically never private.
You're right, the code you provided could lock on any object. However, it didn't. It locked on a private instance field--a field which only that instance can access. That means that no other code can possibly lock on that object. You didn't, in this case, lock on some other object because if some other code locked on it, then you'd have to wait for it (and it may never be released).
"Malicious" code could lock on any object, but it only hurts other code if that other code attempts to lock on the same object. My creating your own private object to lock on, you protect yourself from locks by other code.
synchronized is actually effective for multithreaded environment. This method is to allow concurrency in your system.
When an object is synchronized, the first thread that "touched" the object puts a lock on that object until that thread that is using the locked object finished using the object and releases it. It prevents many threads to change the same object concurrently.
Locks are always on objects.
purpose of syncronized block is to guard objects (one associated with block) with locks, So this means only thread which has lock for object can enter this block.
There is nothing wrong with it, There can be situation in code where you don't need to synchronize complete method but just few lines of code.
One use of synchronization block is in situation when state of object (and other objects related to it) needs to changed in multi threaded env, But the Class of this object doesn't have synchronized methods to alter state of object.
In such situation synchronization is achieved using such block.
Locks should be private iff there will be no reason for any lock related to your class to be held while no thread is actually running code in your class (or code called from code in your class). If you need to e.g. allow someone to maintain exclusive control over your object between operations, you'll have to expose a lock. This opens up many potential issues, including deadlock, so it's generally best if you can design your interfaces and contracts so as to render such extended locking unnecessary.
BTW, note that performing callbacks while holding a lock is slightly less dangerous than exposing a lock, but only slightly. You would eliminate the danger that a caller might acquire a lock and simply forget about it, but the danger of deadlock would still remain.

is this class thread safe?

consider this class,with no instance variables and only methods which are non-synchronous can we infer from this info that this class in Thread-safe?
public class test{
public void test1{
// do something
}
public void test2{
// do something
}
public void test3{
// do something
}
}
It depends entirely on what state the methods mutate. If they mutate no shared state, they're thread safe. If they mutate only local state, they're thread-safe. If they only call methods that are thread-safe, they're thread-safe.
Not being thread safe means that if multiple threads try to access the object at the same time, something might change from one access to the next, and cause issues. Consider the following:
int incrementCount() {
this.count++;
// ... Do some other stuff
return this.count;
}
would not be thread safe. Why is it not? Imagine thread 1 accesses it, count is increased, then some processing occurs. While going through the function, another thread accesses it, increasing count again. The first thread, which had it go from, say, 1 to 2, would now have it go from 1 to 3 when it returns. Thread 2 would see it go from 1 to 3 as well, so what happened to 2?
In this case, you would want something like this (keeping in mind that this isn't any language-specific code, but closest to Java, one of only 2 I've done threading in)
int incrementCount() synchronized {
this.count++;
// ... Do some other stuff
return this.count;
}
The synchronized keyword here would make sure that as long as one thread is accessing it, no other threads could. This would mean that thread 1 hits it, count goes from 1 to 2, as expected. Thread 2 hits it while 1 is processing, it has to wait until thread 1 is done. When it's done, thread 1 gets a return of 2, then thread 2 goes throguh, and gets the expected 3.
Now, an example, similar to what you have there, that would be entirely thread-safe, no matter what:
int incrementCount(int count) {
count++;
// ... Do some other stuff
return this.count;
}
As the only variables being touched here are fully local to the function, there is no case where two threads accessing it at the same time could try working with data changed from the other. This would make it thread safe.
So, to answer the question, assuming that the functions don't modify anything outside of the specific called function, then yes, the class could be deemed to be thread-safe.
Consider the following quote from an article about thread safety ("Java theory and practice: Characterizing thread safety"):
In reality, any definition of thread safety is going to have a certain degree of circularity, as it must appeal to the class's specification -- which is an informal, prose description of what the class does, its side effects, which states are valid or invalid, invariants, preconditions, postconditions, and so on. (Constraints on an object's state imposed by the specification apply only to the externally visible state -- that which can be observed by calling its public methods and accessing its public fields -- rather than its internal state, which is what is actually represented in its private fields.)
Thread safety
For a class to be thread-safe, it first must behave correctly in a single-threaded environment. If a class is correctly implemented, which is another way of saying that it conforms to its specification, no sequence of operations (reads or writes of public fields and calls to public methods) on objects of that class should be able to put the object into an invalid state, observe the object to be in an invalid state, or violate any of the class's invariants, preconditions, or postconditions.
Furthermore, for a class to be thread-safe, it must continue to behave correctly, in the sense described above, when accessed from multiple threads, regardless of the scheduling or interleaving of the execution of those threads by the runtime environment, without any additional synchronization on the part of the calling code. The effect is that operations on a thread-safe object will appear to all threads to occur in a fixed, globally consistent order.
So your class itself is thread-safe, as long as it doesn't have any side effects. As soon as the methods mutate any external objects (e.g. some singletons, as already mentioned by others) it's not any longer thread-safe.
Depends on what happens inside those methods. If they manipulate / call any method parameters or global variables / singletons which are not themselves thread safe, the class is not thread safe either.
(yes I see that the methods as shown here here have no parameters, but no brackets either, so this is obviously not full working code - it wouldn't even compile as is.)
yes, as long as there are no instance variables. method calls using only input parameters and local variables are inherently thread-safe. you might consider making the methods static too, to reflect this.
If it has no mutable state - it's thread safe. If you have no state - you're thread safe by association.
No, I don't think so.
For example, one of the methods could obtain a (non-thread-safe) singleton object from another class and mutate that object.
Yes - this class is thread safe but this does not mean that your application is.
An application is thread safe if the threads in it cannot concurrently access heap state. All objects in Java (and therefore all of their fields) are created on the heap. So, if there are no fields in an object then it is thread safe.
In any practical application, objects will have state. If you can guarantee that these objects are not accessed concurrently then you have a thread safe application.
There are ways of optimizing access to shared state e.g. Atomic variables or with carful use of the volatile keyword, but I think this is going beyond what you've asked.
I hope this helps.

Java Thread - Synchronization issue

From Sun's tutorial:
Synchronized methods enable a simple strategy for preventing thread interference and memory consistency errors: if an object is visible to more than one thread, all reads or writes to that object's variables are done through synchronized methods. (An important exception: final fields, which cannot be modified after the object is constructed, can be safely read through non-synchronized methods, once the object is constructed) This strategy is effective, but can present problems with liveness, as we'll see later in this lesson.
Q1. Is the above statements mean that if an object of a class is going to be shared among multiple threads, then all instance methods of that class (except getters of final fields) should be made synchronized, since instance methods process instance variables?
In order to understand concurrency in Java, I recommend the invaluable Java Concurrency in Practice.
In response to your specific question, although synchronizing all methods is a quick-and-dirty way to accomplish thread safety, it does not scale well at all. Consider the much maligned Vector class. Every method is synchronized, and it works terribly, because iteration is still not thread safe.
No. It means that synchronized methods are a way to achieve thread safety, but they're not the only way and, by themselves, they don't guarantee complete safety in all situations.
Not necessarily. You can synchronize (e.g. place a lock on dedicated object) part of the method where you access object's variables, for example. In other cases, you may delegate job to some inner object(s) which already handles synchronization issues.
There are lots of choices, it all depends on the algorithm you're implementing. Although, 'synchronized' keywords is usually the simplest one.
edit
There is no comprehensive tutorial on that, each situation is unique. Learning it is like learning a foreign language: never ends :)
But there are certainly helpful resources. In particular, there is a series of interesting articles on Heinz Kabutz's website.
http://www.javaspecialists.eu/archive/Issue152.html
(see the full list on the page)
If other people have any links I'd be interested to see also. I find the whole topic to be quite confusing (and, probably, most difficult part of core java), especially since new concurrency mechanisms were introduced in java 5.
Have fun!
In the most general form yes.
Immutable objects need not be synchronized.
Also, you can use individual monitors/locks for the mutable instance variables (or groups there of) which will help with liveliness. As well as only synchronize the portions where data is changed, rather than the entire method.
synchronized methodName vs synchronized( object )
That's correct, and is one alternative. I think it would be more efficient to synchronize access to that object only instead synchronize all it's methods.
While the difference may be subtle, it would be useful if you use that same object in a single thread
ie ( using synchronized keyword on the method )
class SomeClass {
private int clickCount = 0;
public synchronized void click(){
clickCount++;
}
}
When a class is defined like this, only one thread at a time may invoke the click method.
What happens if this method is invoked too frequently in a single threaded app? You'll spend some extra time checking if that thread can get the object lock when it is not needed.
class Main {
public static void main( String [] args ) {
SomeClass someObject = new SomeClass();
for( int i = 0 ; i < Integer.MAX_VALUE ; i++ ) {
someObject.click();
}
}
}
In this case, the check to see if the thread can lock the object will be invoked unnecessarily Integer.MAX_VALUE ( 2 147 483 647 ) times.
So removing the synchronized keyword in this situation will run much faster.
So, how would you do that in a multithread application?
You just synchronize the object:
synchronized ( someObject ) {
someObject.click();
}
Vector vs ArrayList
As an additional note, this usage ( syncrhonized methodName vs. syncrhonized( object ) ) is, by the way, one of the reasons why java.util.Vector is now replaced by java.util.ArrayList. Many of the Vector methods are synchronized.
Most of the times a list is used in a single threaded app or piece of code ( ie code inside jsp/servlets is executed in a single thread ), and the extra synchronization of Vector doesn't help to performance.
Same goes for Hashtable being replaced by HashMap
In fact getters a should be synchronized too or fields are to be made volatile. That is because when you get some value, you're probably interested in a most recent version of the value. You see, synchronized block semantics provides not only atomicity of execution (e.g. it guarantees that only one thread executes this block at one time), but also a visibility. It means that when thread enters synchronized block it invalidates its local cache and when it goes out it dumps any variables that have been modified back to main memory. volatile variables has the same visibility semantics.
No. Even getters have to be synchronized, except when they access only final fields. The reason is, that, for example, when accessing a long value, there is a tiny change that another thread currently writes it, and you read it while just the first 4 bytes have been written while the other 4 bytes remain the old value.
Yes, that's correct. All methods that modify data or access data that may be modified by a different thread need to be synchronized on the same monitor.
The easy way is to mark the methods as synchronized. If these are long-running methods, you may want to only synchronize that parts that the the reading/writing. In this case you would definie the monitor, along with wait() and notify().
The simple answer is yes.
If an object of the class is going to be shared by multiple threads, you need to syncronize the getters and setters to prevent data inconsistency.
If all the threads would have seperate copy of object, then there is no need to syncronize the methods. If your instance methods are more than mere set and get, you must analyze the threat of threads waiting for a long running getter/setter to finish.
You could use synchronized methods, synchronized blocks, concurrency tools such as Semaphore or if you really want to get down and dirty you could use Atomic References. Other options include declaring member variables as volatile and using classes like AtomicInteger instead of Integer.
It all depends on the situation, but there are a wide range of concurrency tools available - these are just some of them.
Synchronization can result in hold-wait deadlock where two threads each have the lock of an object, and are trying to acquire the lock of the other thread's object.
Synchronization must also be global for a class, and an easy mistake to make is to forget to synchronize a method. When a thread holds the lock for an object, other threads can still access non synchronized methods of that object.

Java: What, if anything, is locked by synchronized methods apart from the object they belong to?

Now, I'm not sure whether this is a stupid question, please bear with me if it is.
Is the lock on an object "recursive", i. e. if two objects have references to a third object in their fields and a thread is running a synchronized method on one of the two, can any other thread access the third object?
// a and b are some objects that implement Runnable
// they both reference the same third object
a.ref = c;
b.ref = c;
// a is run in a thread and processes some data in a loop for a long time
// the method the loop belongs to is declared synchronized
threadA = new Thread(a);
threadA.start();
a.someSyncedMethod(); // this would block ...
b.ref.someOtherSyncedMethod(); // ... but would this?
a.ref.someOtherSyncedMethod(); // ... and how about this?
It's worth separating out the concepts of "a lock" and "locking an object". There's no real idea of "locking an object" - there's "acquiring (and releasing)" the lock associated with an object. Yes, it sounds like I'm nitpicking - but the distinction is important because if you talk about an object being locked it sounds like no other threads will be able to change anything in the object while that lock is held.
Instead, it just means that no other thread will be able to acquire the same lock while the lock is held. There's no direct relationship between the lock and any of the contents of the object that the lock is associated with.
Methods declared "synchronized" acquire the lock associated with the instance of the object they belong to. This only makes other synchronized methods on the same object wait, and synchronized statements that explicitly sync on it.
Personally I don't like synchronized methods - I like to make it clearer by explicitly synchronizing on a (private, final) member variable which is only used for synchronization.
a.someSyncedMethod(); // this would block ...
Only if you mark either the run method with synchronized or have ThreadA run code in synchronized methods.
In the JVM, each object owns what's known as a monitor. Only one thread can own the monitor associated with a given object at a time. Synchronized is the means by which you tell the current thread to go get the monitor before continuing.
Also the class itself owns a monitor for static methods.
The meaning of a "lock" (actually this variant is called a monitor) is entirely a convention, no access restrictions are enforced.
The functioning relies on all objects being well-behaved and acquiring the corresponding lock before accessing the data. Only by encapsulating this desired behaviour within in a class with proper access controls you can enforce it for the client objects.

Categories