首页 > 解决方案 > 使用特定对象引用的 Java 同步块

问题描述

我正在使用下面的代码来阻止对 Auction 对象的并发访问。它从哈希映射中获取对象,因此它可以在各种不同的拍卖中运行。

我使用了一个同步块,其中引用了被选为参数的单个拍卖对象。我的印象是,它持有对象监视器的锁,并且会阻止对线程的访问,也使用相同的拍卖(直到第一个案例完成)。

任何人都可以确认此代码的行为方式是:1)如果两个线程都引用拍卖 A,那么只有一个线程可以在时间进行 2)如果一个线程引用拍卖 A 和另一个拍卖 B,那么它们都会在获得不同的锁时继续进行。

    //Get auction from hashmap
    Auction biddingAuction = (Auction) auctions.get(ID);

    //Check that auction is active
    if(biddingAuction != null)
    {
        //Acquire lock on Auction object
        synchronized(biddingAuction) {

       //Some code that alters values of Auction

       }

    } else {
        return "\nBid failed - no auction with an ID of " + ID + " was found\n";
    }

任何澄清将不胜感激,谢谢

标签: javaconcurrencyreferencesynchronized

解决方案


任何人都可以确认此代码的行为方式是 1)如果两个线程都引用拍卖 A,那么只有一个线程可以同时进行

不,两个线程都必须在拍卖中同步才能获得该保证。如果一个线程不同步,即使另一个线程持有它的锁,它也可以访问拍卖。

这就是为什么这种做法非常脆弱的原因:如果您忘记在访问拍卖的可变共享状态(无论是写入还是读取)之前进行同步,那么您的代码就不是线程安全的。一种更简洁的方法是使 Auction 类本身是线程安全的,方法是正确同步访问其共享可变状态的方法。

如果一个线程引用了 Auction A 和另一个 Auction B,那么它们都会在获得不同的锁时继续进行。

是的。那是对的。


推荐阅读