发生了一些奇怪的事情。当我进入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
在此之后发生长暂停。这是为什么 ?当第一个线程还没有离开块时,两个线程如何进入同步块?
答案 0 :(得分:4)
如果两个线程针对同一个对象运行,那么这不应该发生。
因此我建议为每个线程创建一个新对象,或者至少有一些线程在不同的对象上运行。
如果你确实想要多个对象,那么你应该不使用synchronized(this)
,你应该创建一个static final Object
到synchronize
。 1}}请不要因为中断而同步。
答案 1 :(得分:0)
您很可能在包含类的不同实例上调用getNextAvailableVm()
。由于您在this
上进行同步,因此您将锁定两个不同的监视器(实例1上的第一个线程锁,实例2上的第二个线程锁)。
有很多方法可以解决这个问题:
synchronized
this.getClass()
这些只是解决您问题的一些建议,但要找到合适的建议,我们必须了解您的应用程序结构和要求。
答案 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