Monday, 30 January 2012

Synchronization pitfall

Synchronized method modifier is equivalent to block synchronized(this). Not only invoking of such methods is expensive for virtual machine, but they're also a little bit risky. Object's monitor can be taken not only during method invocation, but also by another object that has a reference to it.
Let's take a look at this example:
public class Resource {
private Object veryImportantObject = new Object();
private final Object mutex = new Object();
public synchronized Object getVeryImportantObject() {
System.out.println("Getting object");
return veryImportantObject;
}
public Object getVeryImportantObjectWithMutex() {
synchronized(mutex) {
System.out.println("Getting object with mutex");
return veryImportantObject;
}
}
}
view raw Resource.java hosted with ❤ by GitHub
Class Resource contains some object and provides synchronized methods for fetching it.
getVeryImportantObject() has synchronized modifier.
getVeryImportantObjectWithMutex() uses synchronized block on private object.

We also have an evil class:
public class Cheater {
private final Resource resource;
public Cheater(Resource resource) {
this.resource = resource;
}
public void blockResource() {
synchronized(resource) {
System.out.println("I'm blocking resource");
while(true) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
view raw Cheater.java hosted with ❤ by GitHub
Cheater owns a reference to Resource and it blocks it in blockResource() method.

The class that glues it together:
public class Pitfall {
public static void main(String[] args) throws Exception {
final Resource resource = new Resource();
Executors.newSingleThreadExecutor().submit(new Runnable() {
@Override
public void run() {
new Cheater(resource).blockResource();
}
});
Thread.sleep(1000);
Executors.newSingleThreadExecutor().submit(new Runnable() {
@Override
public void run() {
resource.getVeryImportantObject();
}
});
Executors.newSingleThreadExecutor().submit(new Runnable() {
@Override
public void run() {
resource.getVeryImportantObjectWithMutex();
}
});
}
}
view raw Pitfall.java hosted with ❤ by GitHub
Pitfall invokes 3 threads. The first one uses Cheater to take the monitor of created object of Resource class. Next threads start after 1 second in order to allow the first one performing its task. The second thread tries to get resource object by using method with synchronized modifier, however it never succeeds. The third thread grabs this object by using method with internal synchronized block.
Project Lombok provides an interesting way of not getting into this trap (http://projectlombok.org/features/Synchronized.html)

Saturday, 28 January 2012

Running threads using Executors

There are several ways of running threads.
We can create an instance of Runnable and pass it to Thread class:
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println("thread 1");
}
};
Thread thread1 = new Thread(runnable);
thread1.start();

Or we can override the run() method in the Thread class directly:
Thread thread2 = new Thread() {
@Override
public void run() {
System.out.println("thread 2");
}
};
thread2.start();

However the better solution (in most cases) is using the Executor interface.
It gives us a couple of benefits. In previous cases, if we want to start again the thread that has come to the terminated state we will get IllegalThreadStateException.
With Executor we can reuse the existing Runnable :
ExecutorService executor = Executors.newSingleThreadExecutor();
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}
};
executor.execute(runnable);
// executing once again
executor.execute(runnable);
executor.shutdown();
To prevent adding any more tasks to our executor we need to call shutdown() method.

What is even more important, it provides the ability to easily switch the implementation of running: using single thread, different kinds of thread pools or even scheduled periodic task.
We would just need to use different static factory method from Executors utility class:
ExecutorService executor = Executors.newFixedThreadPool(2);
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}
};
executor.execute(runnable);
executor.execute(runnable);
executor.shutdown();
This time our runnable is run using two threads from executor's thread pool.

Saturday, 21 January 2012

java.util.concurrent.atomic package


Classes from java.util.concurrent.atomic package allow us to use single variables concurrently without blocking access to them. The typical usage example is increasing the counter that is modified by many threads.

Instead of using the synchronized block, that blocks the access to the counter:
private long counter = 0;
private final Object mutex = new Object();
public void incrementCounter() {
synchronized (mutex) {
counter++;
}
}

or the synchronized method equivalent to the block with 'synchronized(this)':
public synchronized void incrementCounter() {
counter++;
}

you can use AtomicLong class, that guarantees non-blocking access:
private AtomicLong counter = new AtomicLong();
public void incrementCounter() {
counter.incrementAndGet();
}

Method incrementAndGet() besides incrementing counter's value, returns it.

Another typical usage is providing non-blocking access to an object, that is shared by many threads. Instead of synchronizing getter/setters methods:
private Object resource = new Object();
public synchronized Object getResource() {
return resource;
}
public synchronized void setResource(Object resource) {
this.resource = resource;
}

you can use AtomicReference class: