Question

Consider a primitive type variable with lots of threads reading and a few threads writing, will the following code work correctly?

If it will, does it provide better performance than 1). declaring synchronized on all the methods; 2). using an explicit ReadWriteLock?

Is this a common pattern? If not, what pattern is usually used in this situation?

This currently works fine for me, but I feel it's a bit redundant to use both volatile and synchronized.

private volatile int value = 1;

public void func1()
{
    if (value == 1) {
        // do something
    }
}

public void func2()
{
    if (value == 2) {
        // do something
    }
}

public void func3()
{
    if (value == 3) {
        // do something
    }
}

public synchronized void increase()
{
    if (value < 10) value++;
}

public synchronized void decrease()
{
    if (value > 0) value--;
}
Was it helpful?

Solution

Consider a primitive type variable with lots of threads reading and a few threads writing, will the following code work correctly?

I think so.

If it will, does it provide better performance than 1). declaring synchronized on all the methods; 2). using an explicit ReadWriteLock?

I think so, provided that read operations outnumber write requests. However:

  • Unless this counter is highly contended, it probably doesn't matter. Don't waste your time micro-optimizing something unless you have evidence that it is (or will be) a bottleneck.
  • If it really matters to you, benchmark it.
  • Don't be surprised if the relative performance depends on JVM versions / patch levels, JVM options and hardware; e.g. numbers of processors and memory architecture.

Is this a common pattern? If not, what pattern is usually used in this situation?

I don't know if this is common. But my gut feeling is that the most common approach is to just use regular synchronization, and not worry about it. Unless you are dealing with a highly contended data structure, the performance difference between the various approaches will be insignificant to overall application performance.

OTHER TIPS

Yes, it is common, at least to a certain degree :)

The pattern you are using is described in this IBM article -> http://www.ibm.com/developerworks/java/library/j-jtp06197/index.html

(pattern #5, cheap read-write lock trick)

I'm sure it provides better performance, since there is no locking, but whether it is correct depends on the intent of the code. For sure, the behaviour is different from the synchronized case. Whether the behaviour is similar to the lock case depends on where you lock.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top