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

时间:2013-09-09 10:50:00

标签: java multithreading synchronized

发生了一些奇怪的事情。当我进入synchronized块时,我尝试打印Thread的名称。在print语句之后,我进行了100000秒的husge暂停。

@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);
        .
        .
        .
   }
}

但是当运行此方法时,将打印2个线程的名称。

Thread-11
Thread-13

在此之后发生长暂停。这是为什么 ?当第一个线程还没有离开块时,两个线程如何进入同步块?

3 个答案:

答案 0 :(得分:4)

如果两个线程针对同一个对象运行,那么这不应该发生。

因此我建议为每个线程创建一个新对象,或者至少有一些线程在不同的对象上运行。

如果你确实想要多个对象,那么你应该使用synchronized(this),你应该创建一个static final Objectsynchronize

答案 1 :(得分:0)

您很可能在包含类的不同实例上调用getNextAvailableVm()。由于您在this上进行同步,因此您将锁定两个不同的监视器(实例1上的第一个线程锁,实例2上的第二个线程锁)。

有很多方法可以解决这个问题:

  • 制作整个方法synchronized
  • this.getClass()
  • 上的同步
  • 定义要锁定的静态对象
  • 使用java.util.concurrent.locks中的方法来执行锁定

这些只是解决您问题的一些建议,但要找到合适的建议,我们必须了解您的应用程序结构和要求。

答案 2 :(得分:0)

我想下面的编程,会像你期望的那样工作,

锁定在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 线程1 线程1 线程0 线程0

相关问题