ziggy
ziggy

Reputation: 15876

Thread concurrency - Using a string object's lock for synchronisation

class ZiggyTest{

    public static void main(String[] args){

        RunnableThread rt = new RunnableThread();

        Thread t1 = new Thread(rt);
        Thread t2 = new Thread(rt);
        Thread t3 = new Thread(rt);

        t1.start();
        t2.start();
        t3.setPriority(10);
        t3.start();

        try{
            t3.join();
            t2.join();
            t1.join();

            System.out.println("Joined");
        }catch(InterruptedException e){System.out.println(e);}


        Thread t4 = new Thread(new RunnableThread());
        Thread t5 = new Thread(new RunnableThread());
        Thread t6 = new Thread(new RunnableThread());

        t4.start();
        t5.start();
        t6.start();
    }

}

The above test produces the following output

Thread-0
Thread-0
Thread-0
Thread-0
Thread-0
Thread-2
Thread-2
Thread-2
Thread-2
Thread-2
Thread-1
Thread-1
Thread-1
Thread-1
Thread-1
Joined
Thread-3
Thread-3
Thread-4
Thread-4
Thread-3
Thread-4
Thread-5
Thread-4
Thread-3
Thread-4
Thread-5
Thread-3
Thread-5
Thread-5
Thread-5

I don't understand why the last three threads are not using the String object as a shared lock like the first three threads. Even though the last three threads are using a different instance of 'RunnableThread', shouldn't they be synchronized because there is only one copy for 'str' in the string constant pool?

Thanks

Edit

oops.. i forgot to include RunnableThread.

class RunnableThread implements Runnable{

    String str = "HELLO";

    public void run(){
        runMe();
    }

    public synchronized void runMe(){
        for (int a : new int[]{1,2,3,4,5}){
            System.out.println(Thread.currentThread().getName());
        }
    }
}

Upvotes: 0

Views: 160

Answers (1)

Ernest Friedman-Hill
Ernest Friedman-Hill

Reputation: 81684

Your threads are not synchronized on any String object, let alone the same one, so I'm not sure where that idea comes from. They're synchronized on the RunnableThread object itself due to the synchronized keyword in this line:

public synchronized void runMe(){

Using separate RunnableThread objects for the last three threads means they run independently.

Now, if you actually wanted to lock on that global String object, the method would look like

public void runMe(){
    synchronized (str) {
        for (int a : new int[]{1,2,3,4,5}){
            System.out.println(Thread.currentThread().getName());
        }
    }
}

and it would be a good idea to make str final.

Upvotes: 5

Related Questions