In following code one of the thread executes A() without any interference, but after that interference occurs. Shouldn't if a thread has acquired lock on the object, it would have have acquired locks on the fields as well?
Integer i=0;
synchronized A(){
for(i=10;i>0;i--);
}
B(){
synchronized(this.i){ // if i replace this.i with this it works as expected.
for(i=10;i>0;i--);
}
}
"Shouldn't if a thread has acquired lock on the object, it would have have acquired locks on the fields as well?"
Short answer: No. The synchronized-keyword synchronizes only access to the specific object monitor (either explicitly given or implicit in case of method modifiers). It does not acquire any other locks on other objects, and does not care in any way about the values of the fields of the given object.
See also "Intrinsic Locks and Synchronization" in the official Oracle turorials.
Related
I'm a newbie to threads and specifically the synchronized key word.
I understand that a thread's state changes to BLOCKED if it tried to access a synchronized block where another thread already owns the lock.
For reference:
synchronized (objA){
objA.methodA();
}
//some code
objA.methodB();
My question is whether another thread can alter the object objA through another independent method (methodB() in this example). Or does owning the lock mean that no other thread can access/alter objA in any way ie whether or not the alteration code is within the synchronized block?
No. The only thing that owning the monitor (lock) means, is that no other thread can also own it until you give it up.
Of course, that does mean that they can't call any synchronized methods on objA (since that requires acquiring the lock), so if all of the modification methods on objA are synchronized (or use synchronized (this) {...} blocks), then the "no" becomes a "yes."
But if methodB never tries to lock on this (either by being synchronized, or by using a synchronized block), then no amount of locking on objA will block calls to objA.methodB().
Synchronizing on a object locks the monitor of the object.
It means that no synchronized method or synchronized statement on an object can be executed if a thread is already executing in a synchronized statement (or a synchronized method) on this same object.
But things are different for no synchronized methods.
Indeed, any thread may invoke any no synchronized method on objA while a thread is executing in a synchronized statement on this same objA.
I am developing a pool mechanism. Objects in the pool will be used by different threads. Thus I need to guarantee that there will be a happens-before relation when accessing non-final attributes of these objects.
As a given object will be accessed by only one thread at a time, I do not need to guarantee any atomicity. What is more optimized when only happens-before needs to be achieved? To use a synchronized block on a final attribute each time I read or modify one of the non-final attribute? Or to use concurrent classes, such as a ConcurrentMap?
(I am not asking this question for attributes of the pool itself, that obviously needs to provide atomicity; I am only asking this question for the attributes of objects obtained from the pool)
To use a synchronized block on a final attribute each time I read or
modify one of the non-final attribute? Or to use concurrent classes,
such as a ConcurrentMap?
Synchronization is built around an internal entity known as the intrinsic lock or monitor lock. Every object has an intrinsic lock associated with it. By convention, a thread that needs exclusive and consistent access to an object's fields has to acquire the object's intrinsic lock before accessing them, and then release the intrinsic lock when it's done with them.
An implementation of ConcurrentMap i.e., ConcurrentHashMap uses reentrant lock which is mutual exclusive lock, Lock is acquired by lock() method and held by Thread until a call to unlock() method. Though, ReentrantLock provides same visibility and orderings guaranteed as implicit lock, acquired by synchronized keyword, it provides more functionality and differ in certain aspect:
ReentrantLock can be made fair by specifying fairness property to provides lock to longest waiting thread, in case of contention.
provides convenient tryLock() method to acquires lock, only if its available or not held by any other thread, reducing blocking of thread waiting for lock. tryLock() with timeout can be used to timeout if lock is not available in certain time period.
In case of synchronized keyword, a thread can be blocked waiting for lock, for an indefinite period of time and there was no way to control that. ReentrantLock provides a method called lockInterruptibly(), which can be used to interrupt thread when it is waiting for lock.
An example of use reentrant lock can be shown from ConcurrentHashMap's inner replace(K key, V oldValue, V newValue) function implementaion:
boolean replace(K key, int hash, V oldValue, V newValue) {
// called by replace(K key, V oldValue, V newValue)
lock(); // acquire the lock
try {
HashEntry<K,V> e = getFirst(hash);
while (e != null && (e.hash != hash || !key.equals(e.key)))
e = e.next;
boolean replaced = false;
if (e != null && oldValue.equals(e.value)) {
replaced = true;
e.value = newValue;
}
return replaced;
} finally {
unlock(); // unlock
}
}
There are other functions like put(), writeObject(java.io.ObjectOutputStream), etc. are also implemented using reentrant synchronization using the ReentrantLock, without which, synchronized code would have to take many additional precautions to avoid having a thread cause itself to block. That is why I think for your case ConcurentMap is preferable.
Reference:
Intrinsic Locks and Synchronization
ReentrantLock Class
Difference between synchronized vs ReentrantLock
ConcurrentHashMap
As a given object will be accessed by only one thread at a time, I do
not need to guarantee any atomicity.
If I get it right, what you mean is that your objects will be shared accross threads, but there is actually no concurrency going on (objects are never accessed concurrently by multiple threads). You're wondering what synchronization is needed.
I've been wondering the same, and my conclusion was the following: if object Y synchronizes accesses to object X, object X doesn't need to be synchronized itself. In the case of a pool, you probably obtain and release objects using methods that are synchronized, so they protect the object in the pool.
Let's consider object O in the pool. The pool has two methods Object acquire() and release(Object o) that are synchronized. To pass object O from thread T1 to T2, T1 must first release O, and T2 must then acquire O. There is already a happen-before relationship between T1's release and T2's acquire, so the object O doesn't need to be itself synchronized.
If the field you need the happens-before relationship on is a primitive, and you are using Java 5 or later, then you can use the volatile keyword which in Java 5+ ensures happens-before reading.
If it's an object, then you need to use some kind of synchronization either using the synchronized key word or a class from the java.util.concurrent package which often has better performance than naive synchronization. For example, ConcurrentHashMap usually has better performance than Collections.synchronizedMap(Map) because it uses separate locks for each bin so there is less lock contention.
well if you need to guarantee a Happens-Before, i think you can create a Synchronized block, holding the Object you want to lock, then in this block, do what you want it to be done before using this object, then invoke your stuff from the Object, then release
for instance
public void doSomething(){
synchronized(myObject){
doAnotherThing();
myObject.doStuff();
}
}
i didnt try the ConcurrentMap before by the way ... and by the way, please clarify your example because i think i didnt get you right !!
I have a class in java that reads UDP packets and puts them in an object (in a basically infinite loop). This object is then accessed in multiple separate threads, but obviously, since it is being filled at the same time, all these getters/setters are in synchronized methods. Problem is, right now these getters have code like this:
public synchronized SomeObject exampleGetter() {
if(this.isReceiving)
return oldCachedObject;
else
return currentObject;
}
Obviously, that's not quite the best way of doing things, so how should I go about writing methods (lots of different ones) that totally lock the object to one thread at a time and block the others (including the thread that created the object in the first place)? I looked at synchronized blocks, but I am kinda confused as to what effect the "lock object" has, is that the object that has access to the block at that given time? Any advice would be appreciated. Thanks!
The synchronized keyword synchronizes on the whole object instance not just the setter. I would rather go for a fine grained locking strategy or better... use a thread safe data structure where you store and get the received data. I personally love the BlockingQueue<T> where T is the type of data you receive on the network.
So suppose you are receiving Objects over a socket:
public class ReceivedDataHolder{
BlockingQueue<Object> dataBuffer = new LinkedBlockingQueue<Object>();
//...
public void dataReceived(Object data){
dataBuffer.offer(data);
}
public Object getReceivedData(){
return dataBuffer.take();
}
}
And in your socket you could do this whenever you receive data:
receivedDataHolder.dataReceived(object);
Any thread that wants to get data should do:
receivedDataHolder.getReceivedData();
This latter method call will block the calling thread until there is an element available on the queue (check this out for more details)
I hope this helps
Maybe AtomicReference would be suitable for you.
See:
java.util.concurrent.atomic
Java volatile reference vs. AtomicReference
All objects in java has something called Intrinsic locks, If any thread wants to do any operation on any object then it needs to acquire the intrinsic lock of that object. it will guarantee that only 1 thread will process your block of code at any given time.
A thread can acquire lock on any object, if that object is not locked by any other thread, if it is locked then the thread will wait till the other thread releases the lock on that object.
if you use synchronized block, your code will be somewhat like this
public void SomeObject exampleGetter() {
synchronized(this)
{
if(this.isReceiving)
return oldCachedObject;
else
return currentObject;
}
In this case when your thread enters the synchronized block, if any other thread is having lock on this object, then it will wait till that thread releases the lock. and if that object is free then your thread will acquire the lock on this object and perform the operation and then release the lock on that object.
for further information on synchronized blocks, methods and intrinsic locks, refer
http://docs.oracle.com/javase/tutorial/essential/concurrency/locksync.html
I hope it helped you :)
so let's say that I have a static variable, which is an array of size 5.
And let's say I have two threads, T1 and T2, they both are trying to change the element at index 0 of that array. And then use the element at index 0.
In this case, I should lock the array until T1 is finished using the element right?
Another question is let's say T1 and T2 are already running, T1 access element at index 0 first, then lock it. But then right after T2 tries to access element at index 0, but T1 hasn't unlocked index 0 yet. Then in this case, in order for T2 to access element at index 0, what should T2 do? should T2 use call back function after T1 unlocks index 0 of the array?
Synchronization in java is (technically) not about refusing other threads access to an object, it about ensuring unique usage of it (at one time) between threads using synchronization locks. So T2 can access the object while T1 has synchronization lock, but will be unable to obtain the synchronization lock until T1 releases it.
You synchronize (lock) when you're going to have multiple threads accessing something.
The second thread is going to block until the first thread releases the lock (exits the synchronized block)
More fine-grained control can be had by using java.util.concurrent.locks and using non-blocking checks if you don't want threads to block.
1) Basically, yes. You needn't necessarily lock the array, you could lock at a higher level of granularity (say, the enclosing class if it were a private variable). The important thing is that no part of the code tries to modify or read from the array without holding the same lock. If this condition is violated, undefined behaviour could result (including, but not limited to, seeing old values, seeing garbage values that never existed, throwing exceptions, and going into infinite loops).
2) This depends partly on the synchronization scheme you're using, and your desired semantics. With the standard synchronized keyword, T2 would block indefinitely until the monitor is released by T1, at which point T2 will acquire the monitor and continue with the logic inside the synchronized block.
If you want finer-grained control over the behaviour when a lock is contended, you could use explicit Lock objects. These offer tryLock methods (both with a timeout, and returning immediately) which return true or false according to whether the lock could be obtained. Thus you could then test the return value and take whatever action you like if the lock isn't immediately obtained (such as registering a callback function, incrementing a counter and giving feedback to a user before trying again, etc.).
However, this custom reaction is seldom necessary, and notably increases the complexity of your locking code, not to mention the large possibility of mistakes if you forget to always release the lock in a finally block if and only if it was acquired successfully, etc. As a general rule, just go with synchronized unless/until you can show that it's providing a significant bottleneck to your application's required throughput.
I should lock the array until T1 is finished using the element right?
Yes, to avoid race conditions that would be a good idea.
what should T2 do
Look the array, then read the value. At this time you know noone else can modify it. When using locks such as monitors an queue is automatically kept by the system. Hence if T2 tries to access an object locked by T1 it will block (hang) until T1 releases the lock.
Sample code:
private Obect[] array;
private static final Object lockObject = new Object();
public void modifyObject() {
synchronized(lockObject) {
// read or modify the objects
}
}
Technically you could also synchronize on the array itself.
You don't lock a variable; you lock a mutex, which protects
a specific range of code. And the rule is simple: if any thread
modifies an object, and more than one thread accesses it (for
any reason), all accesses must be fully synchronized. The usual
solution is to define a mutex to protect the variable, request
a lock on it, and free the lock once the access has finished.
When a thread requests a lock, it is suspended until that lock
has been freed.
In C++, it is usual to use RAII to ensure that the lock is
freed, regardless of how the block is exited. In Java,
a synchronized block will acquire the lock at the start
(waiting until it is available), and leave the lock when the
program leaves the block (for whatever reasons).
Have you considered using AtomicReferenceArray? http://download.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/atomic/AtomicReferenceArray.html It provides a #getAndSet method, that provides a thread safe atomic way to update indexes.
T1 access element at index 0 first, then lock it.
Lock first on static final mutex variable then access your static variable.
static final Object lock = new Object();
synchronized(lock) {
// access static reference
}
or better access on class reference
synchronized(YourClassName.class) {
// access static reference
}
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.