v11
v11

Reputation: 2234

Why does the synchronized lock another method?

I'm new to multiple-thread in java.I write some class to test functions of synchronized.I have some method using synchronized:

    public class ShareUtil {
        private static Queue<Integer> queue = new LinkedList<Integer>();
        public static synchronized void do1(){
            System.out.println("do1");
            sleep();
        }
        public static synchronized void do2(){
            System.out.println("do2");
            sleep();
        }
        private static void sleep(){
            try {
                Thread.sleep(1000*50000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
}

You can see there are two method using synchronized,and I run two thread to use these two methods respectively.

class Run1 implements Runnable{

    @Override
    public void run() {
        // TODO Auto-generated method stub
        ShareUtil.do1();
    }

}
class Run2 implements Runnable{

    @Override
    public void run() {
        // TODO Auto-generated method stub
        ShareUtil.do2();
    }

}
public class DoMain {
    public static void main(String[] args) {
        ExecutorService pools = Executors.newCachedThreadPool();
        for(int i=0;i<10;i++){
            pools.execute(new Run1());
            pools.execute(new Run2());
        }
        pools.shutdown();
    }
}

But,it just print "do1" not print "do2".I want to know why?the key of "synchronized" using method to make the method only one thread use at the same time,but why lock the others method?

Upvotes: 0

Views: 112

Answers (4)

doubleDai
doubleDai

Reputation: 33

I alter the code Thread.sleep(1000*50000); to Thread.sleep(1000*2); the output turns out to be irregular.

do2
do1
do1
do1
do1
do1
do1
do1
do1
do2
do2
do2
do2
do2
do2
do2
do2
do2
do1

We can see these thread is waiting for the lock of ShareUtil.class,and the lock is realesed after Thread.sleep,one of the waiting Threads will grab the lock and turn to run.

Upvotes: 0

JaskeyLam
JaskeyLam

Reputation: 15755

The important key is synchronized locks object, not method.

According to https://docs.oracle.com/javase/tutorial/essential/concurrency/locksync.html

Every object has an intrinsic lock associated with it. By convention, a thread that needs exclusive and consistent access to an object's fields has to acquire the object's intrinsic lock before accessing them, and then release the intrinsic lock when it's done with them. A thread is said to own the intrinsic lock between the time it has acquired the lock and released the lock. As long as a thread owns an intrinsic lock, no other thread can acquire the same lock. The other thread will block when it attempts to acquire the lock.

So, ShareUtil 's class intrinsic lock(your method is static, so this is the intrinsic lock for the Class object associated with the class) is locked when Thread T1 is doing do1(), no other thread can acquire this lock unless T1 release it.

And the method sleep() you call does not release this lock , while if you call wait() it will , check Difference between wait() and sleep(). This is is the reason why when another Thread T2 try to access do2(), it must wait T1's do1() to complete(intrinsic lock is released).

Upvotes: 5

Nageswara Rao
Nageswara Rao

Reputation: 964

Run1() starts first acquires lock on the class ShareUtil, Followed by Run2() which is blocked until Run1() releases the lock. Once Run2() get the lock it will print do2(). Synchronized key guarantees only one thread access the method by acquiring lock on on class if the method is static or "object" if the method is instance.

Upvotes: 0

BatScream
BatScream

Reputation: 19700

Because when you synchronize a static method, it acquires the lock on the Class object. Once a thread has a lock on the Class Object, none of the other threads can enter another static method of the same class.

When you invoke sleep() on a thread when it has the lock, None of the other threads can access the other static methods, because The thread does not lose ownership of the lock.

Hence sleep() is causing only either of the thread to execute their methods. You can also get sometimes do2 printed but not do1.

Upvotes: 1

Related Questions