这一定有一个简单的答案,但我只是不知道它是什么。。。如果我在java中执行以下操作:
class First{
public void first(){
Second second=new Second();
synchronized(this){
second.second(this);
}
second.second(this);
}
}
我怎么办理登机手续 Second.second
在调用此方法之前已经获得了同步锁,如果不是这样,可能会抛出异常?例如:
class Second{
public void second(First first){
if(!/*want to test that lock obtained for first, but don't know how*/){
throw new RuntimeException("Must lock first!");
}
}
}
我要第二个电话 Second.second
扔掉 RuntimeException
如果这对上面的代码不明显。
2条答案
按热度按时间um6iljoc1#
有一种方法:)
但是,你不想这样。
你想要的是:
如果一个线程持有一个锁,然后你再次同步它,这是免费的,而且不会破坏任何东西:它不需要时间,也不会冻结你的线程。您可以重新获取线程已经持有的锁。java维护一个计数器(锁是可重入的)。
要求调用者获得这个锁似乎很愚蠢;为什么不自己去弄呢?如果调用者已经获得了它,没问题。不浪费时间,代码继续工作。
注意:就代码风格而言,抛出runtimeexception是不好的,而在消息中加一个感叹号是非常不好的(想想看;异常中90%以上的消息会以错误结尾!查看日志会变得很烦人)。我认为你也不需要像这样提前离开。因此,如果您必须使用“check-and-throw”样式,那么编写代码段时会为您应用一些修复:)
yyyllmsg2#
我希望第二次调用second.second时抛出runtimeexception,如果这对上面的代码不明显的话。
我认为这是个坏主意。要么你想第一个处理锁,第二个不关心,要么第二个处理锁,不管它是第一个还是第三个。
如果我们将它与标准库中的类进行比较,我们可能会看到hashmap与concurrentmap。hashmap是一个非线程安全类——也就是说,它与示例中的second相同。concurrentmap是一个“线程安全”类,也就是说,它处理自己的同步操作。
这实际上取决于“threadsafe”的构成,因此需要更多关于如何使用类的知识,以了解线程安全的concurrentmap方法是否真正提供线程安全。
除了first之外,是否还有其他人可以访问second的同一个示例,并且您正从这个Angular 防范多线程访问?如果是这样,concurrentmap方法可能更合适。在多线程环境中,second本身是否发生多个操作?如果是这样,首先手动锁定会更合适。
第二个使用map的多个操作的例子。
对于这个简单的代码段,无论Map是hashmap还是concurrentmap,我们都不能防止“thismap is too small”被添加两次。因此,尽管concurrentmap提供了“线程安全”,但这段代码实际上并不是线程安全的。因此,我们需要一个外部锁:
因此,在这种情况下,concurrentmap不会提供任何好处,使用更简单的hashmap将是正确的选择。