java - 使用特定对象引用的 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";
}
任何澄清将不胜感激,谢谢
解决方案
任何人都可以确认此代码的行为方式是 1)如果两个线程都引用拍卖 A,那么只有一个线程可以同时进行
不,两个线程都必须在拍卖中同步才能获得该保证。如果一个线程不同步,即使另一个线程持有它的锁,它也可以访问拍卖。
这就是为什么这种做法非常脆弱的原因:如果您忘记在访问拍卖的可变共享状态(无论是写入还是读取)之前进行同步,那么您的代码就不是线程安全的。一种更简洁的方法是使 Auction 类本身是线程安全的,方法是正确同步访问其共享可变状态的方法。
如果一个线程引用了 Auction A 和另一个 Auction B,那么它们都会在获得不同的锁时继续进行。
是的。那是对的。
推荐阅读
- c - 在扫描复数计算器的数字之前扫描运算符会出错,但在数字后扫描运算符时不会出错
- ruby-on-rails - 如果 Rails Runner 消失,为什么它不会重新连接到数据库?
- java - 如何使用 MVC 结构暂停
- microsoft-graph-api - 无法使用 Graph API 在 Microsoft Teams 中回复第三方导入的消息
- python - 限制 Wagtail Steamfield 中特定 DocumentChooserBlock() 块的文件类型
- c++ - SSH 会话不会通过 cpp reboot 命令终止,而是通过 CLI 命令重新启动
- deep-learning - COCO 上的 Darknet 预训练权重如何适应不同的输出大小(不同的类数)?
- node.js - 如何在本地安装 npm 包?
- css - 定位Vue组件的最佳方式
- blazor - Blazor - 处理多个父母