等待线程是否重新访问synchronized方法内的代码

2024-03-18

我正在阅读有关线程同步和等待/通知结构的内容tutorial http://docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html。它指出

当调用 wait 时,线程释放锁并暂停执行。在将来的某个时间,另一个线程将获取相同的锁并调用 Object.notifyAll,通知所有等待该锁的线程发生了重要的事情。

在第二个线程释放锁一段时间后,第一个线程重新获取锁并通过从 wait 调用返回来恢复。

AFAIK,如果有多个线程可以在第一个线程被唤醒时竞争锁notify,其中任何一个都可以拥有该对象上的锁。我的问题是,如果第一个线程本身重新获取锁,它是否必须从同步方法的开头重新开始(这意味着,它再次在 while 循环检查 wait() 条件之前执行代码)或者它只是暂停在wait() line?

// Does the waiting thread come back here while trying to own the
// lock (competing with others)?
public synchronized notifyJoy() {
    // Some code  => Does this piece of code gets executed again then in case
    // waiting thread restarts its execution from the method after it is notified?
    while (!joy) {
        try {
            // Does the waiting thread stay here while trying to re-acquire
            // the lock?
            wait();
        } catch(InterruptedException e) {}
    }
    // Some other code
}
        

仅当执行该方法的线程完成执行其 run 方法时,方法才会退出,无论是正常返回还是抛出在该 run 方法中未捕获的异常。你的方法的唯一途径not直到上述事情之一发生时才会执行,即 JVM 从您的下面被杀死(使用 java.lang.System.exit,使用 Kill -9 杀死 java 进程等),或者该方法正在运行在 JVM 正在关闭的守护线程中。这里没有什么奇怪的事情发生。等待的线程放弃锁并进入休眠状态,但它不会以某种方式停止执行该方法。

从 wait 调用中唤醒的线程永远不会去任何地方;在线程等待的整个过程中,它仍然处于 wait 方法中。在它离开 wait 方法之前,它首先必须获取它放弃的锁才能开始等待。然后,它需要重新测试需要检查的任何条件,然后才能知道是否继续等待。

这就是为什么受保护的块教程 http://docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html告诉你等待必须在循环中完成:

wait 的调用不会返回,直到另一个线程发出可能发生某些特殊事件的通知 - 尽管不一定是该线程正在等待的事件:

public synchronized void guardedJoy() {
    // This guard only loops once for each special event, which may not
    // be the event we're waiting for.
    while(!joy) {
        try {
            wait();
        } catch (InterruptedException e) {}
    }
    System.out.println("Joy and efficiency have been achieved!");
}

注意:始终在循环内调用 wait 来测试正在等待的条件。不要假设中断是针对您正在等待的特定条件的,或者条件仍然为真。

(本教程使用的措辞具有误导性;“中断”一词应该是“通知”。此外,不幸的是,所示的教程代码在没有设置中断标志的情况下吃掉了 InterruptedException,最好让 InterruptedException 从这个方法根本没有捕获它。)

如果线程确实“重新开始”,那么就不需要这个循环;您的代码将从方法的开头开始,获取锁,并测试正在等待的条件。

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

等待线程是否重新访问synchronized方法内的代码 的相关文章

  • java.lang.NoSuchMethodError: org.mockito.Mockito.framework()Lorg/mockito/MockitoFramework

    我一直面临一个特殊的问题 基本上 当我正常运行 Mockito 测试 即 作为 Junit 测试运行 时 它会出现以下错误 有人可以帮我看看我的错误是什么吗 收到的错误 java lang NoSuchMethodError org moc
  • 如何处理或避免BlockedIndefinitelyOnSTM异常?

    我花了很多时间来解决我正在处理的应用程序中遇到的问题 该应用程序是一个 Web 应用程序 使用 scotty 公开 REST 端点 它使用一个TVar保持其更新的状态STM a由前端层触发的动作 由于该应用程序基于事件溯源原则 因此业务层生
  • 我们可以实例化一个抽象类吗?

    在一次采访中 有人问我 我们是否可以实例化一个抽象类 我的回答是 不 我们不能 但是 面试官告诉我 错了 我们可以 我对此争论了一下 然后他告诉我自己在家尝试一下 abstract class my public void mymethod
  • 将数据传递到表单时的重定向后获取?

    我有几个场景 servlet 需要将数据从数据库检索到的记录传递到 JSP 中的表单 目前 我将此信息存储在请求中 使用 RequestDispatcher 转发到页面 一切都很好 然而 这不符合 PRG 模式 AFAIK 并且当然意味着刷
  • Java 7 中的 Beans Binding 将被什么取代?

    我在某处读到 我忘记了链接 Beans Binding 将不会成为 Java 7 的一部分 有人知道什么会取代它吗 另外 当前版本的 Java 中是否有 Bean 绑定的替代方案 我建议JGoodies 绑定 https binding d
  • Java 应用程序可以检测到调试器已连接吗?

    我知道 jvm 启动选项可以让 jvm 等待附加调试器 这不是我在这里的意思 是否有可能从 Java 代码中也检测调试器的附件 以便我可以例如编写一个正在执行某些操作的 脚本 然后在某个时刻让我的应用程序等待调试器 不会 这些选项是 JVM
  • 使用 GIN 注入 Class

    有没有办法注入类类型Class
  • 如何仅使用命令行运行 Maven 创建的 jar 文件

    我需要一些帮助来尝试使用命令行运行以下 Maven 项目 https github com sarxos webcam capture https github com sarxos webcam capture webcam captur
  • 使用pdfbox从pdf中提取图像

    我正在尝试使用 pdfbox 从 pdf 中提取图像 示例 pdfhere http www ignou ac in upload questionpaper CS 74 PDF 但我只得到空白图像 我正在尝试的代码 public stat
  • 为什么在此单元测试中,BackgroundWorker 没有在正确的线程上调用 RunWorkerCompleted?

    backgroundWorker 的全部目的是在执行耗时的任务后更新 UI 组件正如广告所宣传的那样在我的 WPF 应用程序中 但是在我的测试中 回调不会在调用线程上调用 Test public void TestCallbackIsInv
  • Netty UDP 服务器中的线程未同时执行

    我正在分析的代码使用 Netty NioDatagramChannelFactory 创建 UDP 服务器 它创建一个线程池 ExecutorService threadPool Executors newCachedThreadPool
  • CellTables 和 css (GWT)

    有人可以帮我设置 CellTable 行的背景吗 拜托 我整晚都在努力做这件事 但一直失败 这是 让我发疯 我尝试过调用setRowStyles 但是那个 似乎不起作用 我读到你无法更改 设置样式后 CellTable 的样式 作为默认样式
  • JavaFX:在 WebView img 标签中未加载本地图像

    以下是我的代码 一切安好 我可以加载远程页面 我可以放置 HTML 内容 但我的img标签显示一个X标志表示无法加载图像 Note 我的图像与类位于同一个包中JavaFX在 Smiley 文件夹中 我可以列出所有图像 这意味着路径没有问题
  • 更新 Maven 项目模块中的父版本

    我有一个奇怪的场景 我有一个项目 Y 它有一个模块 X 和一些其他模块 X 是项目 Y 的一部分 但它不作为该项目的模块链接 因此 每次发布 Y 的新版本时 都需要有人手动更新 X 中的父版本 我需要以这样的方式更新 Y 项目 a 每次发布
  • 使用 JavaFX 和 Maven 将模块描述符添加到库中[重复]

    这个问题在这里已经有答案了 我需要使用反思 https github com ronmamo reflections在一个带有 JavaFX 的 Maven 项目中 我想使用jlink捆绑一个最小的 JRE 问题是我运行时出现以下错误mvn
  • 从子线程绘制到窗口

    我的应用程序从工作线程绘制图形已有 10 多年了 而且我从未遇到过任何问题 工作线程吸引到我的HWND 由主线程创建 如下所示 hdc GetDC hwnd SetDIBitsToDevice or StretchDIBits Releas
  • JFrame 类型的方法 ... 未定义

    我正在尝试制作一个带有两个菜单列表的 gui 每个菜单列表有 3 个项目 我的问题是 当我单击某个项目时 出现错误 JFrame 类型的方法 displayList int AirplaneList 未定义 AirplaneControll
  • 设置滚动条粗细

    有没有办法调整滚动条的粗细JScrollPane 默认值有点笨拙 一个快速但又肮脏的解决方案是将宽度 高度明确设置为例如10 像素通过 jScrollPane getVerticalScrollBar setPreferredSize ne
  • Eclipse IDE - 错误:构建路径指定执行环境 Java SE 1.7

    在 Eclipse 中 我收到一个错误 构建路径指定执行环境Java SE 1 7 工作区中没有安装与此环境严格兼容的 JRE 尝试这个 In Eclipse your project gt properties gt java build
  • Jsplitpane 自动调整大小

    我有一个 JSPlitPane 它们之间有 50 的分隔线 这工作正常 但是 当我在右侧添加一些 JLabels 时 jsplitpane 会忽略我的 50 分隔符 左侧窗格会增加其大小 并会挤压右侧窗格 为什么会发生这种情况以及如何解决

随机推荐

  • 使用加法、减法和减半计算三角根

    特定游戏的规则是角色的力量与角色的力量成正比 三角根 https math stackexchange com q 698961 93170角色的经历 例如 15 20经验获得5力量 21 27经验获得6力量 28 35经验获得7力量等等
  • UIWebView 以更有效的方式减少加载时间

    我正在下载多个 html 并将它们作为字符串保存在本地NSArray 然后我用3UIWebViews加载内容 用户总是看到一个UIWebView还有 2 个UIWebViews使用以下方式在后台加载 firstWebView loadHTM
  • 将属性添加到 php 中对象顶部的 stdClass

    当创建一个对象时php用于返回 JSON 是否可以添加一个属性并强制它位于顶部 我想要这个 因为该对象是通过 API 公开的 并且最好在顶部有 id 例如 obj new stdClass obj gt name John obj gt a
  • 如何在 C++ 中限制生成的程序可以使用的内存量

    在我的 C 程序中 我将启动其他程序 如果这些程序使用超过一定量的内存 我希望我的程序杀死它们的进程 那怎么办呢 我可能会使用 execv 来启动程序 假设您使用的是 POSIX 系统 您可以通过调用来限制这一点setrlimit 2 af
  • Linux 上的 .NET core X509Store

    使用 NET Core 2时 Linux中的证书文件位于哪里X509Store 在 Windows 上 可以从管理控制台访问证书certlm msc或与New SelfSignedCertificate在 powershell 中 使用 N
  • 为什么 Xcode 6 将动态链接编辑器库中的自动完成功能保持为 TRUE?

    我仍在学习 Swift 和 iOS 开发 但我一直遇到这个问题 尽管我尝试深入了解一下 但我仍然有点困惑 当我开始打字时trueXcode 6 建议自动完成TRUE 不是世界末日 然而 有一次我决定看看如果我使用会发生什么TRUE结果给了我
  • Spring尤里卡中的instanceid是什么?

    我读到 Eureka 客户端的实例 ID 必须是唯一的 当我们希望运行同一 Eureka 客户端的多个实例时 我们添加此属性 eureka instance instance id spring cloud client hostname
  • 如何依次请求多个权限?

    我的应用程序需要访问CAMERA and 写外部存储权限 一旦我的应用程序加载 我想要求用户依次允许这两个权限 我有这个代码 if ContextCompat checkSelfPermission this Manifest permis
  • 如何仅提取 .tar.gz 成员的文件?

    我的目标是打开包装 tar gz文件 而不是指向该文件的子目录 我的代码基于此question https stackoverflow com questions 4917284 extract files from zip without
  • 图论。如何处理此类问题?我想知道解决这个问题时的逻辑和思考方式。

    求笛卡尔平面上从 0 0 到 n n 的路径数 该路径永远不会高于 y x 线 可以沿着路径进行三种类型的移动 move up i e from i j to i j 1 move to the right i e from i j to
  • Lua中字符串的串联

    在许多语言中 您可以在变量赋值时连接字符串 我有一个使用 Lua 编程语言的场景 我需要将命令的输出附加到现有变量 Lua 中是否有与以下示例等效的功能 其他语言的例子 PERL filename checkbook filename tm
  • C# 带有 new 和 get 整数的构造函数

    这是 Unity 5 5 0 上的结构我对 C 很陌生 不太了解属性和结构 这会在分配期间出现错误this X 我假设您无法更改结构上的值 并且关键字 this 指的是结构的属性 在控制返回给调用者之前 必须完全分配自动实现的属性 Poin
  • 返回php文件中图像的内容?

    我真的不懂 PHP 但我想做一件简单的事情 我从 a 中访问 php 页面 img src myhumbleimage php 我想要从另一个 URL 返回图像 我想出了
  • 什么是布尔标志

    我正在学习 Visual Basic 2010 课程 并试图掌握这个称为 标志 的新术语 我有点理解它与布尔条件有关 我不太明白flag是什么 我看到使用术语 标志 来引用它 我知道当布尔值 条件触发标志时 它会发生一些事情 但旗帜是什么
  • 如何在android sqlite中删除单行

    I have sqlite数据表示在ListView by a CustomListAdapter 单击一行时alert dialogue弹出提示用户删除单行sqlite在我的活动中 private void deleteDialog Al
  • 如何在多 HttpSecurity 情况下返回 http 状态代码而不是登录页面

    我有一个 Spring Boot 应用程序 它通过以下方式提供 HTML 页面服务 还有rest api通过 api 前者需要通过登录表单登录 后者需要HTTP基本身份验证 因此 我配置了两个HttpSecurity部分如下 Configu
  • 以编程方式阻止 Windows 屏幕保护程序启动

    是否有推荐的方法来阻止 Windows 屏幕保护程序启动 我发现的最接近的是本文 http www codeproject com KB cs ScreenSaverControl aspx 但我真正想做的只是告诉 Windows 计算机没
  • Angular 2抛出错误:插座未激活

    我已经设置了我的应用程序 以便我有一个Recipe Book其中有一个列表Recipies当我点击食谱时 它会显示Recipe Details在嵌套路由中 然后 它还有一个按钮 单击该按钮会将成分加载到嵌套路径中Recipes Detail
  • 如何在 Vim 中普遍使用相对行号

    我喜欢 Vim 7 3 中的相对行编号功能 但我很难让它普遍适用 对于许多文件 行编号会恢复为绝对模式 即使我已指定 set rnu in my vimrc文件 知道是什么原因造成的吗 我在 OSX 10 6 上使用 Vim 7 3 以及
  • 等待线程是否重新访问synchronized方法内的代码

    我正在阅读有关线程同步和等待 通知结构的内容tutorial http docs oracle com javase tutorial essential concurrency guardmeth html 它指出 当调用 wait 时