简体   繁体   English

两个线程如何同时进入同步块?

[英]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. 当我进入同步块时,我尝试打印线程的名称。在打印语句之后,我暂停了100000秒。

@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. 如果你想多个对象,那么你应该使用synchronized(this) ,你应该建立一个static final Object ,以synchronize的。 Please do not sync on this.getClass() as that breaks. 请不要在this.getClass()上同步,因为这样会中断。

Most likely you are invoking getNextAvailableVm() on different instances of the containing class. 您很可能在包含类的不同实例上调用getNextAvailableVm() Since you are synchronizing on this you will be locking on two different monitors (first thread locks on instance1, second one on instance2). 由于您正在this进行同步, this您将锁定在两个不同的监视器上(第一个线程锁定在instance1上,第二个锁定在instance2上)。

There are a lot of ways you could correct this: 有很多方法可以纠正此问题:

  • make the whole method synchronized 使整个方法synchronized
  • synchronize on this.getClass() this.getClass()上同步
  • define a static object to lock on 定义要锁定的静态对象
  • use methods from java.util.concurrent.locks to do the locking 使用java.util.concurrent.locks中的方法进行锁定

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 锁定在Thread1.Class上,两个线程不会同时执行该方法

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 输出线程1线程1线程0线程0

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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