简体   繁体   中英

How could the two threads enter the synchronized block at the same time?

There is some weird thing happening. As I enter the synchronized block,I try to print the name of the Thread.After the print statement,I make a husge pause of 100000 seconds.

@Override
public int getNextAvailableVm() {
    synchronized(this) {

        System.out.println(Thread.currentThread().getName());

        try {Thread.sleep(100000000);}catch(Exception exc){}

        String dataCenter = dcc.getDataCenterName();
        int totalVMs = Temp_Algo_Static_Var.vmCountMap.get(dataCenter);
        AlgoHelper ah = (AlgoHelper)Temp_Algo_Static_Var.map.get(dataCenter);
        .
        .
        .
   }
}

But as this method is run,name oft the 2 threads are printed.

Thread-11
Thread-13

and it is after this that the long pause occurs. Why is that ? How could the two threads enter the synchronized block,when the first thread has yet not left the block ?

If the two threads are running against the same object then this should not happen.

I would therefore suggest that you are creating a new object for each thread or at least some of the threads are running on different objects.

If you do want multiple objects then you should not use synchronized(this) , you should create a static final Object to synchronize on. Please do not sync on this.getClass() as that breaks.

Most likely you are invoking getNextAvailableVm() on different instances of the containing class. Since you are synchronizing on this you will be locking on two different monitors (first thread locks on instance1, second one on instance2).

There are a lot of ways you could correct this:

  • make the whole method synchronized
  • synchronize on this.getClass()
  • define a static object to lock on
  • use methods from java.util.concurrent.locks to do the locking

These are just some suggestions to address your problem, but to find the right one we would have to know more about your application structure and your requirements.

I guess the below prog, will work like you expected,

Locked on Thread1.Class, Two thread will not execute the method simultaneously

public class Test {
    public static void main(String [] args) { 
        Thread1 t1 = new Thread1();
        Thread1 t2 = new Thread1();
        t1.start();
        t2.start();
    }
}

class Thread1 extends Thread{
    public void run(){
        getNextAvailableVm();
    }
    public void getNextAvailableVm() {
        synchronized(Thread1.class) {
            System.out.println(Thread.currentThread().getName());
            try {
                Thread.sleep(1000);
                }catch(Exception exc){}
            System.out.println(Thread.currentThread().getName());
        }

    }
}

OUTPUT Thread-1 Thread-1 Thread-0 Thread-0

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM