2 回答
TA贡献1777条经验 获得超3个赞
我不认为这是一个骗局,因为尽管有标题,但实际问题是 OP 的具体实现。代码中有一个错误,这不是方法与块的问题。
代码中的错误是您尝试实现锁定机制的地方。在incr()中,您等到available设置为 false,这仅发生在getVal():
public synchronized void incr() {
while (available) { // <-- bug
try {
wait();
由于您的循环只调用incr()而不调用getVal(),因此两个线程在第一次调用incr(). (你getVal()最终会调用,但只有在内循环完成之后。两个线程都很好并且到那时卡住了。)
解决方案:AtomicInteger没有像这样的奇怪错误。如果您尝试实现某种生产者/消费者机制,那么其中一个并发队列(如ArrayBlockingQueue)是更好的解决方案。
TA贡献1909条经验 获得超7个赞
同步方法和块之间的一个显着区别是,同步块通常会减少锁定范围。由于锁定范围与性能成反比,因此只锁定代码的关键部分总是更好。使用同步块的最佳示例之一是 Singleton 模式中的双重检查锁定,
getInstance()
我们只锁定用于创建 Singleton 实例的代码的关键部分,而不是锁定整个方法。这极大地提高了性能,因为锁定只需要一两次。同步块提供了对锁的精细控制,因为您可以使用任意锁来为关键部分代码提供互斥。另一方面,同步方法总是锁定由 this 关键字表示的当前对象或类级别锁定,如果它的静态同步方法。
如果作为参数提供给块的表达式计算为 null,则同步块可以抛出 throw
java.lang.NullPointerException
,而同步方法则不是这种情况。在同步方法的情况下,线程进入方法时获取锁,离开方法时释放锁,正常或抛出异常。另一方面,在同步块的情况下,线程进入同步块时获取锁,离开同步块时释放。
添加回答
举报