Java 两个线程如何同时进入同步块?
发生了一些奇怪的事情。当我进入synchronized块时,我尝试打印线程的名称。在print语句之后,我进行100000秒的husge暂停Java 两个线程如何同时进入同步块?,java,multithreading,synchronized,Java,Multithreading,Synchronized,发生了一些奇怪的事情。当我进入synchronized块时,我尝试打印线程的名称。在print语句之后,我进行100000秒的husge暂停 @Override public int getNextAvailableVm() { synchronized(this) { System.out.println(Thread.currentThread().getName()); try {Thread.sleep(100000000);}catch(Ex
@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);
.
.
.
}
}
但在运行此方法时,将打印两个线程的名称
Thread-11
Thread-13
在这之后,长时间的停顿发生了。为什么呢?当第一个线程尚未离开同步块时,两个线程如何才能进入同步块?如果两个线程针对同一对象运行,则不应发生这种情况 因此,我建议您为每个线程创建一个新对象,或者至少有一些线程在不同的对象上运行
如果您确实需要多个对象,那么您应该不使用
同步(this)
,您应该创建一个静态最终对象
以同步
。请不要在this.getClass()
上同步,因为它会中断。很可能是在包含类的不同实例上调用getNextAvailableVm()
。由于您在上进行同步,因此将在两个不同的监视器上锁定(第一个线程锁定在instance1上,第二个线程锁定在instance2上)
有很多方法可以纠正此问题:
- 使整个方法
同步
- 在
this.getClass()上同步
- 定义要锁定的静态对象
- 使用java.util.concurrent.locks中的方法进行锁定
这些只是解决您的问题的一些建议,但要找到正确的建议,我们必须更多地了解您的应用程序结构和需求。我想下面的程序会像您预期的那样工作
锁定在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());
}
}
}
输出
线程-1
线程-1
线程-0
Thread-0您确定正在同一对象上调用getNextAvailableVm()
吗?您确定睡眠没有中断吗?(打印异常块中的内容)@njzk2无法从异常中打印任何内容block@SuhailGupta:可能是因为没有打印声明?@rocketboy comment可能是您的问题。如果在同一对象上正确同步,则没有理由让多个线程访问此块。请不要在getClass()
上同步。如果开始包含子类,则会中断。如何在此.getClass()上进行同步中断?在ClassName.class上同步也是如此吗?@jenschauder-如果在this.getClass
上同步,则当任何对象同步时,此类型的所有对象都将被阻止。此外,对象的子类也将无法与超类的对象正确同步。这几乎肯定不是你想要的。