2

Please see the program below

public class TestVolatile implements Runnable {

    public static volatile int counter;
    public static String lock = "lock";

    public static void main(String[] args) {
        Thread t1 = new Thread(new TestVolatile(),"Thread-1");
        Thread t2 = new Thread(new TestVolatile(),"Thread-2");
        t1.start();
        t2.start();
    }

    public void run() {
        synchronized(this) {
            System.out.println(Thread.currentThread()+"-"+counter);
            counter++;
        }
    }
}

If I run this program multiple times, I get 3 different results.

first is

Thread[Thread-1,5,main]-0
Thread[Thread-2,5,main]-0

second is

Thread[Thread-1,5,main]-0
Thread[Thread-2,5,main]-1

third is

Thread[Thread-1,5,main]-1
Thread[Thread-2,5,main]-0

But if change the lock object from "this" to "lock", I get 2 different results

first is

Thread[Thread-1,5,main]-0
Thread[Thread-2,5,main]-1

second is

Thread[Thread-1,5,main]-1
Thread[Thread-2,5,main]-0

My assumption when writing the program was that in either case the "counter" should never come 0 in both statements.
Can somebody explain?

1

2 Answers 2

3

You create two TestVolatile objects. The "this" keyword refers to the TestVolatile object being run in the thread. Thus you do not synchronize on the same object in the first example.

If you change the code like this, then the first example starts working:

public static void main(String[] args) {
    TestVolatile testVolatile = new TestVolatile();
    Thread t1 = new Thread(testVolatile,"Thread-1");
    Thread t2 = new Thread(testVolatile,"Thread-2");
    t1.start();
    t2.start();
}
Sign up to request clarification or add additional context in comments.

Comments

1

It's probably not what you're looking for, but if you want to avoid the use of synchronized and volatile, you should use an instance of AtomicInteger: http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/atomic/AtomicInteger.html

Use the getAndIncrement method to show the same behavior as in your example.

public class TestVolatile implements Runnable {

    public static AtomicInteger counter = new AtomicInteger();
    public static void main(String[] args) {
        Thread t1 = new Thread(new TestVolatile(),"Thread-1");
        Thread t2 = new Thread(new TestVolatile(),"Thread-2");
        t1.start();
        t2.start();
    }

    public void run() {
        System.out.println(Thread.currentThread() + " - " + counter.getAndIncrement());
    }

}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.