Synchronized block not blocking object

I am trying to acquire a lock on an object for 10 seconds. I expect any other thread to have to wait 10 seconds to use this object when it syncs.

Here is the code:

public class Test {

    Student student1=new Student(1,"sachin");

    Thread thread1 = new Thread("My Thread 1"){
        public void run(){
                synchronized(student1){
                    try {
                        System.out.println("in thread1,acquired student1 and will wait for 10 sec");
                        sleep(10000);
                        System.out.println("Leaving the lock on student1");
                    } catch (InterruptedException e) {
                    }
                }
            }
    };

    Thread thread2 = new Thread("My Thread 2"){
        public void run(){
            System.out.println(String.valueOf(student1.name) +"   "+ student1.roll);
        }
    };

    public class Student {
        int roll;
        String name;
        public Student(int roll,String name)
        {
            this.name=name; this.roll=roll;
        }
    }

    public static void main(String a[]){
        Test test = new Test();
        test.thread1.start();
        test.thread2.start();
    }
}

      

Output:

in thread1, acquired student1 and will wait for 10 sec
sachin   1
Leaving the lock on student1

      

Expected Result:

in thread1, acquired student1 and will wait for 10 sec
Leaving the lock on student1
sachin   1

      

I expect this because thread2

I won't be able to access student1

until the thread leaves the lock on it.

+3


source to share


3 answers


Thread 2 is not synchronized on student1

. That's why he doesn't wait. You need to sync both threads.



+4


source


This is because you are not syncing your student1

link access in the Thread2 run () method.

System.out.println(String.valueOf(student1.name) +"   "+ student1.roll);

      

it should be



synchronized(student1){
  System.out.println(String.valueOf(student1.name) +"   "+ student1.roll);
}

      

when you talk synchronized(student1)

in the run1 method of a thread, thread1 will acquire a lock on that student1 object, enter a synchronized block, and execute the code inside that block.

Any subsequent attempts by any other thread to acquire a lock on the same reference will student1

block that thread until thread1 releases the lock by exiting the synchronized block. Threads will be blocked only when they request a lock on an already locked object, any other instances of the same class or any other access to the methods / fields of locked objects without synchronization are always allowed.

+1


source


In your example, thread2 does nothing to try to acquire the lock used by thread1. Referencing fields on the object does not acquire locks, what you need to do is enter a synchronized block or method that uses the same lock (student1).

If you've added a syncronized method to the Student:

public synchronized String getName() {
    return name;
}

      

and ask thread2 to call it while thread1 is running, changing the code in the run2 method to:

System.out.println(String.valueOf(student1.getName()) +"   "+ student1.roll);

      

then thread2 will not be able to acquire the lock on student1 to enter the getName method while thread1 is holding on to it and you should see the lock:

c:\Users\ndh>java Test
in thread1,acquired student1 and will wait for 10 sec
Leaving the lock on student1
sachin   1

      

Remember, when you start two threads it is a race to see where to start over, it doesn't guarantee that thread1 will always run before thread2.

0


source







All Articles