Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Thread synchronization- When does a thread release the lock on an object

public class MyStack2 {
    private int[] values = new int[10];
    private int index = 0;

    public synchronized void push(int x) {
        if (index <= 9) {
            values[index] = x;
            Thread.yield();
            index++;
        }
    }

    public synchronized int pop() {
        if (index > 0) {
            index--;
            return values[index];
        } else {
            return -1;
        }
    }

    public synchronized String toString() {
        String reply = "";
        for (int i = 0; i < values.length; i++) {
            reply += values[i] + " ";
        }
        return reply;
    }
}

public class Pusher extends Thread {
    private MyStack2 stack;

    public Pusher(MyStack2 stack) {
        this.stack = stack;
    }

    public void run() {
        for (int i = 1; i <= 5; i++) {
            stack.push(i);
        }
    }
}

public class Test {
    public static void main(String args[]) {
        MyStack2 stack = new MyStack2();
        Pusher one = new Pusher(stack);
        Pusher two = new Pusher(stack);
        one.start();
        two.start();
        try {
            one.join();
            two.join();
        } catch (InterruptedException e) {
        }
        System.out.println(stack.toString());
    }
}

Since the methods of MyStack2 class are synchronised, I was expecting the output as 1 2 3 4 5 1 2 3 4 5. But the output is indeterminate. Often it gives : 1 1 2 2 3 3 4 4 5 5

As per my understanding, when thread one is started it acquires a lock on the push method. Inside push() thread one yields for sometime. But does it release the lock when yield() is called? Now when thread two is started, would thread two acquire a lock before thread one completes execution? Can someone explain when does thread one release the lock on stack object?

like image 770
sam Avatar asked Oct 07 '14 13:10

sam


1 Answers

A synchronized method will only stop other threads from executing it while it is being executed. As soon as it returns other threads can (and often will immediately) get access.

The scenario to get your 1 1 2 2 ... could be:

  1. Thread 1 calls push(1) and is allowed in.
  2. Thread 2 calls push(1) and is blocked while Thread 1 is using it.
  3. Thread 1 exits push(1).
  4. Thread 2 gains access to push and pushes 1 but at the same time Thread 1 calls push(2).

Result 1 1 2 - you can clearly see how it continues.

like image 66
OldCurmudgeon Avatar answered Nov 15 '22 05:11

OldCurmudgeon