How Do Determine If an Object Is Locked (Synchronized) So Not to Block in Java

How do determine if an object is locked (synchronized) so not to block in Java?

One thing to note is that the instant you receive such information, it's stale. In other words, you could be told that no-one has the lock, but then when you try to acquire it, you block because another thread took out the lock between the check and you trying to acquire it.

Brian is right to point at Lock, but I think what you really want is its tryLock method:

Lock lock = new ReentrantLock();
......
if (lock.tryLock())
{
// Got the lock
try
{
// Process record
}
finally
{
// Make sure to unlock so that we don't cause a deadlock
lock.unlock();
}
}
else
{
// Someone else had the lock, abort
}

You can also call tryLock with an amount of time to wait - so you could try to acquire it for a tenth of a second, then abort if you can't get it (for example).

(I think it's a pity that the Java API doesn't - as far as I'm aware - provide the same functionality for the "built-in" locking, as the Monitor class does in .NET. Then again, there are plenty of other things I dislike in both platforms when it comes to threading - every object potentially having a monitor, for example!)

Java: How to check if a lock can be acquired?

You can't do it using the low-level native synchronization embedded in Java. But you can do it using the high-level APIs provided in the concurrent package.

Lock lock = new ReentrantLock();
....
//some days later
....
boolean isLocked = lock.tryLock();

Java will synchronized block if changed?

What happens would really depend on how quickly doA() gets run:

If doA() changes the value of x before doB() reaches its synchronized block, then doB() will lock on the new object that doA() created.

If doB() is speedy and the synchronized(x) part gets evaluated before doA() can change the value of x, then doB() will have to wait until doA()'s synchronized block finishes.

Explanation

Whenever Java gets to the synchronized(x) code in either method, it evaluates the variable x, and that variable gives Java an object. So Java then tries to lock on that object, and stay locked on that object. Or, if there's already a lock on that object, it will wait for the lock to go away. (Whenever Java reaches the synchronized(x) code, it takes the value of the variable and ignores forgets the variable itself, so you can change the variable as you please afterwards, but locking and lock checking still happen on the variable's previous value.)

How can I check if a thread is inside a synchronized block or method?

When entering a synchronized method the VM sets a lock on the current object. Thus the following codes have the same effect:

synchronized void syncMethod() {
// do something
}

void syncManually() {
synchronized (this) {
// do something
}
}

That means the synchronized method does exactly the same as

synchronized( lock ) {
// do something
}

anywhere in your code.

You can use Thread.holdsLock(...) to check if the thread holds a specific lock. Here is an example code:

final Object lock = new Object(); 

public void lockDemo() {

System.out.println( Thread.holdsLock(lock) ); // false
System.out.println( Thread.holdsLock(this) ); // false

synchronized ( lock ) {
System.out.println( Thread.holdsLock(lock) ); // true: locked by object
System.out.println( Thread.holdsLock(this) ); // false
}

doSyncMethod();
}

public synchronized void doSyncMethod() {
System.out.println( Thread.holdsLock(lock) ); // false
System.out.println( Thread.holdsLock(this) ); // true: locked by synchronized method
}

Since Java 1.5 more sophisticated locks like ReentrantReadWriteLock are supported by the java.util.concurrent.locks package.
They can provide separated read and write locking and improve the performance of your application. The Lock Objects chapter of the Oracle Java Tutorials is a good start here.

How synchronize on object without locking?

use an AtomicBoolean, put this code in your MyContainer class:

AtomicBoolean isRefreshing = new AtomicBoolean(false);

void refresh() {
if ( isRefreshing.compareAndSet( false, true)) {
try {
// refresh
} finally {
isRefreshing.set( false);
}
}
}

If you can not touch MyContainer, maybe create a RefreshWrapper holding the AtomicBoolean and the MyContainer instance.

synchronized block not locking the object reference

So, when MyThread1 is executing, due to the synchronized block, the monitor of d should be locked, resulting in denial of access to d.demo() by the MyThread2.

That would only happen if MyThread2 also had a synchronized block. When one thread is synchronized on an object, other threads will be blocked if they also try to synchronize on that same object. If they don't synchronize, they won't be. There's nothing that stops access to an object from threads that don't synchronize on it.

Synchronization is a cooperative mechanism. It only works when all threads work together.



Related Topics



Leave a reply



Submit