JAVA NIO – FileLock

Locking on File introduced with java.nio package that implemented by FileChannel. A FileLock is two types exclusive and shared. A shared lock allows other concurrently running program to acquire overlapping shared Lock. An Exclusive lock doesn’t allow other program to acquire overlapping lock.

Lock ideally supports shared Lock but it depends OS if OS doesn’t support share lock then it will act as exclusive locking. Locking applied on File not per channel or thread means if channel obtained the exclusive lock then other JVM’ channel will be block till first thread channel resume the lock.

 

Locks are associated with a file, not with individual file handles or channels Locking applied on File not per channel or thread means if channel obtained the lock before processing the file then other JVM’ channel will be block till first thread channel resume the lock. Since Lock is on File therefore it is not advisable to use lock on a single JVM.

Below is FileLock API in FileChannel class

 

 

 

 

 

 

 

 

 

 

public abstract class FileChannel extends AbstractInterruptibleChannel implements SeekableByteChannel,
      GatheringByteChannel, ScatteringByteChannel {
public abstract FileLock lock(long position, long size, boolean shared) throws IOException;
   public final FileLock lock() throws IOException {
       return lock(0L, Long.MAX_VALUE, false);
   }
   public abstract FileLock tryLock(long position, long size, boolean shared) throws IOException;
   public final FileLock tryLock() throws IOException {
       return tryLock(0L, Long.MAX_VALUE, false);
   }
}

 

The FileLock (long position, long size, boolean shared) acquire lock on specified part of a file. The region of file specified by beginning position and size whereas last argument specified if lock is shared lock (value True) of exclusive (value False). To obtain the shared lock, you need to open file with read permission whereas write permission require exclusive lock.

We can use lock () method to acquire lock on whole file not the specified area on file. File can grow therefore we need to specify the size while obtaining the lock.

Method tryLock on specified area or on full file doesn’t block/hold while acquiring a lock means it immediately return value without going to wait to acquire lock. If other process already acquired lock for specific file then it will immediate return null.

 

 

 

 

FileLock API specified as below.

public abstract class FileLock {
  public final FileChannel channel( )
   public final long position( )
   public final long size( )
   public final boolean isShared( )
   public final boolean overlaps (long position, long size)
   public abstract boolean isValid( );
   public abstract void release( ) throws IOException;
}

The FileLock encapsulates specific region, which is acquired by FileChannel. FileLock associate with specific FileChannel instance and FileLock keep the reference of FileChannel that could be determining by channel () method in FileLock.

FileLock lifecycle will start when lock method or tryLock invoke from FileChannel and end when release () method called. It FileLock also invalid if JVM shutdown or associated channel closed.

isShared() method return whether lock is shared or exclusive. If shared lock is not supported by operating system then this method always return false.

FileLock objects are thread-safe; multiple threads may access a lock object concurrently.

Finally, overlaps(long position, long size) return if lock overlap the given block range or not.

FileLock object associated with an underlying file which occurred deadlock if you don’t release the lock hence it is advisable to always release lock as mentioned below

 

 

FileLock lock = fileChannel.lock( )
try {
       ..............
} catch (IOException) [
       ..................
} finally {
   lock.release( )
}

Java Interview Reference Guide – Synchronization

Synchronization

The synchronized modifier is used to control access to critical code in multi-threaded program. The synchronized keyword is one of the tools that make your code thread safe. The “Synchronized” modifier in Java prevents concurrent access code block or methods by multiple threads. Synchronized force threads to obtain a lock before entering the method and release the lock after completing the method. It ensures that only one thread can execute the method at a time.

If we make method or block as synchronized then it will not allow more than one invocations on synchronized method on the same object. If one method invoke synchronized method other thread block until the first thread complete the method execution.

First method acquires the lock of that object before entering the synchronized method of the same object and releases it to acquire by other threads. Synchronize method use happens-before relationship, which guarantees that changes to the state of object are visible to all threads

When you mark a block of code as synchronized you use an object as a parameter. When an executing thread comes to such a block of code, it has to first wait until there is no other executing thread in a synchronized block on that same object. However a thread could enter the block of synchronized method other object. But non-synchronized method in same object can access without checking lock.

if you synchronize on a static method you will synchronize on the class (object) and not on an instance (object). That means while execution of a static method the whole class is blocked. So other static synchronized methods are also blocked

1) When a thread has entered a synchronized instance method then no other thread can enter any of synchronized instance methods of the same instance

2) When a thread entered a synchronized static method then no other thread can enter any of synchronized static methods of the same class

Note: No link between synchronized static methods and non static methods that means Static synchronize and non-static synchronize method can run concurrently unless your non-static method must explicitly synchronize on the class itself (ie, synchronized (MyClass.class) {…}

Note: Constructor of class cannot be synchronized.

Monitor or Intrinsic Lock

 Intrinsic locks enforce restriction on access to an object’s state and establish happens-before relationships.

Every object has an intrinsic lock and a thread has to acquire the object’s intrinsic lock before accessing them and release it when it’s done. Other thread cannot access the object’s state till thread owns its intrinsic lock. It ensure that state change done by a thread will be visible to other thread which synchronize on the same monitor.

After thread release lock which effect of flushing the cache to main memory so that object’s state change will be visible to other thread and that is called happens-before relationship.

The synchronized and volatile constructs, as well as the Thread.start () and Thread.join() methods, can form happens-before relationships.

The locks acquired by synchronized statements are the same as the locks that are acquired implicitly by synchronized methods. A single thread may acquire a lock more than once.

Acquiring the lock associated with an object doesn’t prevent other threads for accessing fields of the object or invoking un-synchronized methods.

The synchronized statement attempts to seek lock of object and the body of synchronized statements executed once it acquire lock of that object and unlock after completing the synchronized statements.

If the method is member or instance of object then it will lock instance for which it was invoked. If the method is static, it locks the monitor associated with the Class object that represents the class in which the method is defined. Synchronize method control by its property-SYNCHRONIZED flag, which is check by method invocation instructions.

Atomic Variable

If we consider int i++ it contains combination of multiple operation e.g. it reads value from memory, increment and puts write back to the memory. This operation is fine for single thread operation but might give wrong answer in multi-thread environment. It also have race issue means multiple thread can read the value at the same time.

Atomic access ensures that action happens all at once. An atomic action occurs completely or doesn’t occur at all.

There are actions you can specify that are atomic:

  1. Reads and writes are atomic for reference variables and for most primitive variables (all types except long and double).
  2. Reads and writes are atomic for all variables declared volatile (including long and double variables).

The java.util.concurrent.atomic package defines classes that support atomic operations on single variables. All classes have get and set methods that work like reads and writes on volatile variables. That means, a set has a happens-before relationship with any subsequent get on the same variable. The atomic compareAndSet method also has these memory consistency features, as do the simple atomic arithmetic methods that apply to integer atomic variables .

In java 5.0 java.util.concurrent.atomic package define classes that supports atomic operation on single operation. The JVM compiles these classes with the better operations provided by the hardware machine, CAS (Compare and Set).

  • AtomicInteger
  • AtomicLong
  • AtomicBoolean
  • AtomicReference

All classes have get and set methods that work like reads and writes on volatile variables. That is, a set has a happens-before relationship with any subsequent get on the same variable. The atomic compareAndSet method also has these memory consistency features, as do the simple atomic arithmetic methods that apply to integer atomic variables

Volatile variable

Only variable may be volatile. Such variable might be modified asynchronously so the compiler takes special precaution

The volatile modifier guarantees that any thread that reads a field will see the most recently written value

Using volatile variables reduces the risk of memory consistency errors, because any write to a volatile variable are always visible to other threads. What’s more, it also means that when a thread reads a volatile variable, it sees not just the latest change to the volatile, but also the side effects of the code that led up the change.

In a multi thread environment object make their own copy of object in threads local cache except volatile variable that means volatile will have only one copy in heap which will updated by thread and immediately reflect to other Thread. There is no flush of local’s thread cache memory after completing the process.

Volatile fixed visibility issue but bring race condition and it will not lock to wait to complete the process for example :

Volatile int i=0

i +=5 invoking by two simultaneously thread give result 5 or 10 but it guarantee to see immediate changes.

Use of volatile: One common example for using volatile is to use a volatile boolean variable as a flag to terminate a thread.

 

Difference between static and volatile variable

Declaring static variable means there will be only copy associated with class it doesn’t matter how many object get created for that class. The static variable will be accessible even with no Objects created at all. Thread may have locally cached values of it.

This means that if two threads update a variable of the same Object concurrently, and the variable is not declared volatile, there could be a case in which one of the threads has in cache an old value. Even if you access a static value through multiple threads, each thread can have its local cached copy!

But a volatile variable will keep only one copy in memory and shared across the threads.

 Difference between Volatile and Synchronize:

So where volatile only synchronizes the value of one variable between thread memories and “main” memory, synchronized synchronizes the value of all variables between thread memory and “main” memory, and locks and releases a monitor to boot. Clearly synchronized is likely to have more overhead than volatile.

A volatile variable is not allowed to have a local copy of a variable that is different from the value currently held in “main” memory. Effectively, a variable declared volatile must have it’s data synchronized across all threads, so that whenever you access or update the variable in any thread, all other threads immediately see the same value.

Lock Objects

Lock object behave same as implicit locks, which is used by synchronized code. As with implicit locks, only one thread can own a Lock object at a time. Lock objects also support a wait/notify mechanism, through their associated condition object.

The biggest advantage of Lock objects over implicit locks is their ability to back out of an attempt to acquire a lock. The tryLock() method backs out if the lock is not available immediately or before a timeout expires (if specified). The lockInterruptibly() method backs out if another threads sends an interrupt before the lock is acquired

 Java garbage collector

Each time an object is created in Java, it goes into the area of memory known as heap. The Java heap is called the garbage collectable heap. The garbage collection cannot be forced. The garbage collector runs in low memory situations. When it runs, it releases the memory allocated by an unreachable object. The garbage collector runs on a low priority daemon (i.e. background) thread. You can nicely ask the garbage collector to collect garbage by calling System.gc() but you can’t force it.

How to write a Deadloack

In some cases in multi thread environment deadlock situation occured means two or more thread are blocked forever, waiting for each other.
Below sample code is an deadlock scenarios:

public class DeadlockSample {
private final Object obj1 = new Object();
private final Object obj2 = new Object();

public static void main(String[] args) {
DeadlockSample test = new DeadlockSample();
test.testDeadlock();
}

private void testDeadlock() {
Thread t1 = new Thread(new Runnable() {
public void run() {
calLock12();
}
});
Thread t2 = new Thread(new Runnable() {
public void run() {
calLock21();
}
});
t1.start();
t2.start();

}
private void calLock12() {
synchronized (obj1) {
sleep();
synchronized (obj2) {
sleep();
}
}
}
private void calLock21() {
synchronized (obj2) {
sleep();
synchronized (obj1) {
sleep();
}
}
}
private void sleep() {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

Explain types of references in Java?

java.lang.ref package can be used to declare soft, weak and phantom references

  • Garbage Collector won’t remove a strong reference.
  •  A soft reference will only get removed if memory is low. So it is useful for implementing caches while avoiding memory leaks.
  •  A weak reference will get removed on the next garbage collection cycle.  Can be used for implementing canonical maps. The java.util.WeakHashMap implements a HashMap with keys held by weak references.

A phantom reference will be finalized but the memory will not be reclaimed. Can be useful when you want to be notified that an object is about to be collected.

References:
http://docs.oracle.com
http://stackoverflow.com/
http://en.wikipedia.org/
Effective Java™