Java同步块使用方法调用来获取同步对象

2024-01-02

我们正在编写一些锁定代码,并遇到了一个特殊的问题。我们使用 ConcurrentHashMap 来获取我们锁定的对象实例。所以我们的同步块看起来像这样

synchronized(locks.get(key)) { ... }

我们重写了 ConcurrentHashMap 的 get 方法,使其在不包含键的情况下始终返回一个新对象。

@Override
public Object get(Object key) {
   Object o = super.get(key);
   if (null == o) {
      Object no = new Object();
      o = putIfAbsent((K) key, no);
      if (null == o) {
         o = no;
      }
   }
   return o;
}

但是有没有一种状态,get方法已经返回了对象,但是线程还没有进入synchronized块。允许其他线程获取相同的对象并锁定它。

我们有一个潜在的竞争条件是

  • 线程1:获取key为A的对象,但不进入synchronized块
  • 线程2:获取带有键A的对象​​,进入同步块
  • 线程2:从映射中删除对象,退出同步块
  • 线程1:进入同步块,对象不再在map中
  • 线程 3:获取键 A 的新对象(与线程 1 获取的对象不同)
  • 线程 3:进入同步块,而线程 1 也在其同步块中,两者都使用键 A

如果 java 在 get 调用返回后直接进入同步块,则不会出现这种情况。如果没有,是否有人对我们如何删除密钥而不必担心这种竞争条件有任何意见?


在我看来,问题源于你锁定了映射值,而实际上您需要锁定key(或者它的一些派生)。如果我理解正确的话,您希望避免 2 个线程使用相同的键运行关键部分。

你可以锁定钥匙吗?你能保证你总是使用同一个密钥实例吗?

一个不错的选择:

根本不要删除锁。用一个参考图 http://commons.apache.org/collections/apidocs/org/apache/commons/collections/map/ReferenceMap.html价值观较弱。这样,只有当当前没有任何线程使用映射条目时,才会删除该条目。

Note:

1) 现在您必须同步此映射(使用 Collections.synchronizedMap(..))。

2)您还需要同步为给定键生成/返回值的代码。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java同步块使用方法调用来获取同步对象 的相关文章

  • 读取文件并获取 key=value 而不使用 java.util.Properties

    我正在构建一个 RMI 游戏 客户端将加载一个包含一些键和值的文件 这些键和值将用于多个不同的对象 它是一个保存游戏文件 但我不能为此使用 java util Properties 它符合规范 我必须读取整个文件并忽略注释行和与某些类不相关
  • 如何在java中压缩/解压tar.gz文件

    谁能告诉我在java中压缩和解压缩tar gzip文件的正确方法我一直在搜索 但我能找到的最多的是zip或gzip 单独 我写了一个包装器公共压缩 http commons apache org compress called jarchi
  • 以点作为分隔符分割字符串

    我想知道我是否要在一个字符串上分割字符串 正确的方式 我的代码是 String fn filename split return fn 0 我只需要字符串的第一部分 这就是我返回第一项的原因 我问这个是因为我在 API 中注意到 意味着任何
  • 在 Android 中绘制一条带有弯曲边缘的线

    I am using canvas drawLine to draw some line in android but the lines are too sharp but i need a curved edges 这里的 1 是我所拥
  • WebLogic 10 中的临时目录

    每当 WL 停止时 它都不会删除其临时目录 即 domains mydomain servers myserver tmp WL TEMP APP DOWNLOADS domains mydomain servers myserver tm
  • java中队列的实现

    在 Java 中实现队列是一个非常常见的面试问题 我在网上冲浪 看到了许多实现 他们做了一些奇特的事情 比如实现队列接口和编写自己的addLast and removeFirst 方法 我的问题是我不能使用LinkedList 类并使用其预
  • 动画图像视图

    目前我正在开发一款游戏 这是我的游戏的详细信息 用户应选择正确的图像对象 我希望图像从左到右加速 当他们到达终点时 他们应该再次出现在活动中 这是我正在处理的屏幕截图 我有 5 个图像视图 它们应该会加速 您有此类动画的示例代码吗 非常感谢
  • 为什么一个线程会中断另一个线程[重复]

    这个问题在这里已经有答案了 在Java多线程应用程序中 我们处理InterruptedThreadException 如果另一个线程中断当前线程 则会抛出此异常 现在 当另一个线程知道它将导致异常时 它可能想要中断当前线程的原因是什么 很多
  • 如何屏蔽 Protobuf 中的某些字段

    我找不到一种方法来屏蔽 protobuf 结构中的某些字段 我确实阅读了有关 FieldMaskUtil 的内容并尝试了几个示例 但它似乎做了相反的操作 即复制 FieldMask 中提到的字段 这与我想要的不同 这是示例结构和相应的测试代
  • 带有面板的 Java Swing JToolbar:外观和感觉

    我有一个JToolbar其中包含多个JPanels 需要 因为我希望每个都有特定的边界 不幸的是 外观管理器无法识别JPanels属于工具栏和JButtons因此 渲染器与普通按钮一样 即没有工具栏上的特殊鼠标悬停效果 更换JPanels
  • JavaFx 中装饰且不可移动的舞台

    我想在 JavaFx 中创建一个装饰舞台 它也将不可移动 我正在从另一个控制器类创建这个阶段 我能够创造和展示舞台 但它是自由移动的 我怎样才能创建这个 非常感谢帮助和建议 我把打开新关卡的方法贴出来 private void addRec
  • 更改 RowLayout SWT Java 中元素的顺序

    有没有办法更改在行布局中创建的元素的顺序 我想将其显示在元素中 首先显示 例如 如果我创建 element1 则 element2 element3 element4 我想看到的布局为 元素4 元素3 元素2 元素1 这意味着最后创建的元素
  • XSLT:我们可以使用abs值吗?

    我想知道在 XSLT 中我们是否可以使用 math abs 我在某处看到过这个 但它不起作用 我有类似的东西
  • 如何列出所有可用的 LookAndFeel 主题?

    如何列出所有可用的 LookAndFeel 主题 我想在 JComboBox 中显示以供用户选择 这真的很简单 public static UIManager LookAndFeelInfo getInstalledLookAndFeels
  • 如何在 Java 中创建要打印到 JFrame 的 JLabels 数组

    我正在尝试制作一系列标签 每个标签都有一个来自函数的不同值 我不知道要使用的标签的确切数量 我的意思是可以打印任意数量的值 请帮我做这件事 很简单 只需一个方法返回一个数组或一些 JLabels 集合 并将它们全部添加到您的 JCompon
  • 在方法内声明类 - Final 关键字 [重复]

    这个问题在这里已经有答案了 给定方法中的以下内部类 IsSomething public class InnerMethod private int x public class Something private int y public
  • Java 8根据Map属性过滤Map对象列表以删除一些重复项

    Have a List
  • 如何使用maven创建基于spring的可执行jar?

    我有一个基于 Maven 的 Spring WS 客户端项目 我想将其打包为单个 jar 在eclipse中 一切运行正常 当我尝试将其打包为可执行 jar 时 我收到 ClassNotFound 异常 因为 Spring jar 未包含在
  • Java中的媒体播放器库[关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我正在评估用于在 Java 中播放音频 视频的库 它不需要 100 Java Java 与本机库的绑定
  • java数据结构模拟数据树

    我需要帮助定义使用什么方法 我有一个 SOAP 响应 给我一个 xml 文件 我需要在屏幕上显示 3 个相关列表 当您在第一个列表中选择一个项目时 相应的选择将出现在第二个列表中 依此类推 我只对从 xml 流中提取数据后如何有效地组织数据

随机推荐

  • 使用 C# 中的架构进行 XML 解析

    我正在编写一些在运行时加载 xml 文件的代码 目前 我们使用 XmlDocument 类型来读取 xml 文件 并在 SelectSingleNode 语句周围包装一个 try catch 这是在节点为 null 或在我们解析用户时不存在
  • iOS 从后台重新检查加载位置

    我正在构建一个应用程序 它根据您当前的位置显示结果数据 目前 我正在使用viewDidLoad的方法UIViewController开始CLLocationManager并获取当前位置 一旦我获得了与我想要的准确性相匹配的位置 我就会向我的
  • 从发布的 JSON 获取经典 ASP 变量

    我正在尝试通过 AJAX 将 JSON 发布到经典 ASP 页面 该页面检索值 检查数据库并将 JSON 返回到原始页面 我可以通过 AJAX 发布 JSON 我可以从 ASP 返回 JSON 我无法将发布的 JSON 检索到 ASP 变量
  • 在 Golang 中导入 C 错误:cc1.exe:错误:给出的文件名太多

    我正在尝试导入并使用 C 包 但我不断收到此错误 runtime cgo cc1 exe error too many filenames given Type cc1 exe help for usage cc1 exe fatal er
  • 将域指向我的远程 Node JS 应用程序?

    我正在尝试弄清楚如何在我的 Ubuntu 10 04 LTS 服务器上准确部署 Node JS 我读过许多不同的博客和文章 它们解释了多种不同的方式 大多数似乎已经过时了 或者看起来并没有真正发挥作用 看来最简单的解决办法就是使用Forev
  • 部分类文件的命名约定

    我正在生成大部分 ASP NET MVC 脚手架代码 所有生成的文件都是使用标准命名约定的部分类 例如 我的员工控制器文件名为 EmployeeController cs 如果我希望使用自定义的非生成逻辑扩展 EmployeeControl
  • Visual Studio 2019:起始页而不是起始窗口

    Visual Studio引入了阻塞Start Window而不是非阻塞Start Page 考虑到Visual Studio的可扩展性如何 有没有办法让VS2019显示非阻塞Start Page The new Start Window非
  • switch 语句:“期望一个常量值”

    目前我正在与 神奇的字符串 问题作斗争 public class MyDataField class definition exuecuted method public void SwitchMultipleDataFields var
  • 如何将三个sql选择组合成一个查询

    我有下面的三个查询 我想将它们合并为一个查询 这样我就可以得到三列 其中包含按县划分的结果 我尝试对所有表进行内部联接 但得到的数据很差 如何组合这三个查询并按县分组 select Total DLL Children SUM cd Num
  • java中通过反射设置对象字段的值

    首先 我有一个这样的对象 public class Entity public int data1 public String data2 public float data3 public SubEntity data4 public c
  • 如何将字节转换为字符串?

    我需要转换我的Byte to a String because NSInteger write const uint8 t buffer maxLength NSUInteger takes a String作为它的第一个参数 我想要的是
  • 需要 root 才能在运行时通过应用程序执行 shell 命令“输入 keyevent <#>”?

    我正在尝试执行 adb shell 命令input keyevent 5在运行时通过我的应用程序接听电话 如果我这样做 Runtime getRuntime exec input keyevent 5 它似乎没有执行 什么也没有发生 但是当
  • 如何在 Azure DevOps 中从 .vdproj 构建安装项目?

    我最近将一些 Windows 应用程序升级到 VS2019 并使用 VS2019 中的 VSInstallerProject 扩展创建了安装项目 我注意到 运行发布管道时 安装程 序并未创建 但我需要此处的 msi 或 exe 文件 以便我
  • Gradle 无法解析来自神器的依赖关系

    我正在尝试构建一个 android library MyLib1 它依赖于 gradle 和 jenkins 中的另一个 android library MyLib2 我有点绝望 因为我认为我的 gradle 文件和设置都没有问题 我成功地
  • Jetpack Compose LazyColumn - 如何分别更新每个项目的值?

    我正在为我的应用程序开发购物车功能 我希望分别添加 减少 LazyColumn 中每个列表项的数量 我只使用一个 记住 因此如果我单击添加 减少 它们都会同时更新 如何单独控制每个项目 截屏 https i stack imgur com
  • 将 TypeScript 转换为 JavaScript

    我想知道如何才能改变打字稿 http www typescriptlang org 以跨平台方式转换为 JavaScript 我知道以下内容的可用性Typescript 的节点包管理器 http www typescriptlang org
  • Hibernate - 通过用户名关系进行加密引用

    我想知道我的想法是否可以用休眠来实现 我想要的是有一个包含用户名的表 并且每个引用该表的表都将用户名加密在一列中 因此 用户名不是以普通文本形式存在 而是在每个引用用户表的表中加密 所以我需要类似的东西 ManyToOne JoinColu
  • 如何使 Visual Studio 始终在 git 更改的新选项卡中查看提交详细信息?

    它在 git 历史记录中的一个小窗口中打开提交详细信息 这非常不方便 因为它太小了 看不到任何东西 每次点击 在新选项卡中打开 很烦人 有没有办法让 Visual Studio 始终在新选项卡中打开它 目前无法直接在新选项卡中打开 提交详细
  • 应用了 Hilt Android Gradle 插件,但未找到 com.google.dagger:hilt-android-compiler 依赖项

    我收到错误 Hilt Android Gradle 插件已应用 但没有com google dagger hilt android compiler发现了依赖关系 在构建项目时 以下是我如何将柄添加到我的项目中 我猜你缺少这种依赖 kapt
  • Java同步块使用方法调用来获取同步对象

    我们正在编写一些锁定代码 并遇到了一个特殊的问题 我们使用 ConcurrentHashMap 来获取我们锁定的对象实例 所以我们的同步块看起来像这样 synchronized locks get key 我们重写了 ConcurrentH