Java的notify()在wait()之前运行?

2023-11-21

public class ThreadA {
    public static void main(String[] args){
        ThreadB b = new ThreadB();
        b.start();

        synchronized(b){
            try{
                System.out.println("Waiting for b to complete...");
                b.wait();
            }catch(InterruptedException e){
                e.printStackTrace();
            }

            System.out.println("Total is: " + b.total);
        }
    }
}

class ThreadB extends Thread{
    int total;
    @Override
    public void run(){
        synchronized(this){
            for(int i=0; i<100 ; i++){
                total += i;
            }
            notify();
        }
    }
}

如上面的例子,如果wait()先块输入,后块输入notify()ThreadB 中的 ThreadB 会告诉主线程继续。

但我们不能保证wait()将在之前执行notify(),如果ThreadB先进入块怎么办?Notify()将在之前执行wait(), so wait()将永远挂在那里(因为不再有notify()告诉它继续)?通常处理这个问题的正确方法是什么?


您几乎应该始终将谓词与等待/通知一起使用。也就是说你需要一个条件 您可以检查,例如变量变为 true,队列变为空/满等。只是盲目地等待某人调用 .notify() 的用例很少。

所以,以下是不行的,因为你说的原因,另一个线程可以在 ThreadA 调用 .wait() 之前调用 .notify()

public class ThreadA {
    public static Object latch = new Object();
    public static void main(String[] args) {
        ThreadB b = new ThreadB();
        b.start();
        synchronized(latch ) {
            latch.wait(); //wait for B to finish a calculation
        }
        System.out.println("Total is: " + b.total);

    }
}

class ThreadB extends Thread {
    int total;

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            total += i;
        }
       synchronized(ThreadA.latch) {
           ThreadA.latch.notify();
       }
    }
}

你需要做这样的事情:

 public class ThreadA {
    public static Object latch = new Object();
    public static boolean done = false;
    public static void main(String[] args) {
        ThreadB b = new ThreadB();
        b.start();
        synchronized(latch ) {
            while (!done) {   //wait for B to indicate it is finished.
                latch.wait(); 
            }
        }
        System.out.println("Total is: " + b.total);

    }
}

class ThreadB extends Thread {
    int total;

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            total += i;
        }
       synchronized(ThreadA.latch) {
           ThreadA.done = true;         
           ThreadA.latch.notify();
       }
    }
}

请注意,在上面的内容中,done变量受同步块保护,.wait()将自动释放/重新获取该锁。所以不存在竞争条件,并且如果在我们到达之前调用 .notify().wait()调用 , ThreadA 会发现因为donetrue并且不输入.wait()根本不打电话。

对于像这段代码这样的简单情况,您可以等待 ThreadB 结束,可以使用b.join();

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

Java的notify()在wait()之前运行? 的相关文章

随机推荐

  • 为什么相同的代码每次运行时给出不同的地址?

    每次运行代码时 我都会得到不同的输出值 当堆和堆栈地址固定时 为什么 malloc 返回不同的地址 我希望它从堆顶部开始分配并每次返回一个固定地址 对于堆栈也是如此 include
  • pymc3 中的自定义可能性

    如何在 PyMC3 中定义自定义可能性 在 PyMC2 中 我可以使用 pymc potential 我尝试使用pymc Potential然而 在 PyMC3 中 布尔运算似乎无法应用于参数 我收到类似的错误this当我这样做时 例如 以
  • IPython Notebook Javascript:从 JavaScript 变量中检索内容

    有没有办法function 由 IPython Notebook 单元调用 来检索 JavaScript 变量的内容 例如IPython notebook notebook path其中包含当前笔记本的路径 当直接在单元格中编写时 例如 基
  • 如何将 Svelte 应用程序放入 Docker 容器中?

    标题基本概括了所有内容 我对网络开发非常陌生 我使用创建了一个 Svelte 应用程序npx degit sveltejs template 现在我使用本地运行它npm run dev or npm start 据我了解 这是一个 Node
  • 在命令行工具中获取资源的路径

    我试图在 Xcode 8 beta 2 的命令行工具中获取资源的路径 这是我所得到的 资源 file xyz 已被拖入项目中 并且目标成员资格与主项目匹配 在 构建阶段 gt 复制文件 下 目标设置为 资源 并且子路径为空 未选中 仅在安装
  • 在 SQL Server 上插入更新存储过程

    我编写了一个存储过程 如果记录存在 它将执行更新 否则它将执行插入 它看起来像这样 update myTable set Col1 col1 Col2 col2 where ID ID if rowcount 0 insert into m
  • 通用对象的通用列表

    假设我有一个代表数据字段的对象 该对象需要以下属性 名称 类型 值 长度 这是对象 class Field
  • SwingX JXTable:使用 ColorHighlighter 根据“行对象”为行着色

    我正在使用 JXTable 并且我知道如何基于 JTable 的 DefaultRenderers 来执行此操作 但我想知道如何以基于 HighlighterPipeline 的 JXTable 友好的方式执行此操作 我有一个表中显示的对象
  • Haskell 错误:输入“=”时解析错误

    Specs GHC 6 12 1 Mac OS X 10 6 4 x64 MacBook Pro Problem 我使用时遇到问题let句法 以下代码拒绝编译 module Main where main let x 1 y 2 z 3 i
  • 将 varchar 转换为数据类型 numeric 时出现算术溢出错误。 ‘10’ <= 9.00

    下面是我正在使用的表结构和数据的子集 CREATE TABLE Test Val varchar 5 Type varchar 5 INSERT Test VALUES Yes Text INSERT Test VALUES 10 Int
  • Quicklook/QLPreviewController 委托方法在 iOS 10 Xcode 8 中不调用

    目前我正在 iOS10 中测试我当前的版本 我在用Xcode 8beta 6 用于测试 这里Quicklook QLPreviewController 委托方法未调用 该代码集适用于 XCode 7 和 iOS 9 3 版本 我在苹果开发者
  • Jetpack Compose 具有动态操作的 TopAppBar

    Composable fun TopAppBar title Composable gt Unit modifier Modifier Modifier navigationIcon Composable gt Unit null acti
  • 如何在python2和python3中运行程序

    我的机器上当前安装了 python 2 6 6 和 python 3 1 3 Windows Vista 64 位 我的路径变量包括两个版本的目录 如何指定要在哪个 python 中运行程序 例如 如果我想在 python 3 中运行程序
  • 静态类变量存储在内存中的什么位置?

    这是一个后续问题静态数组如何存储在Java内存中 所以C C 中的全局变量存储在内存的静态数据段中 但是 Java C 中的静态类变量又如何呢 它不能是静态数据段 因为您不知道在整个程序持续时间内将引用什么 多少个类 由于反射 这绝对不是堆
  • iOS 9 上的 GIDSignIn 白屏

    我实现了 Google 登录 并且在 iOS 8 上一切正常 但是当我在 iOS 9 上调用此行时 GIDSignIn sharedInstance signIn 我可以第一次登录 但如果我取消 下次尝试登录时 它会显示一个白色屏幕 其中是
  • r - data.table 和 testthat 包

    我正在构建一个与 data table 一起使用的包 并且应该使用包 testthat 对其进行测试 虽然从命令行调用时代码工作正常 但从测试用例调用时遇到了问题 运行测试时似乎使用了基础包中的 函数 即 data frames 的函数 我
  • 将 HTTP POST 请求重定向到 HTTPS POST 请求

    我最近刚刚将我的服务器设置为使用 SSL 证书通过 HTTPS 运行 该网站是一个图像托管服务 ShareX 的开发人员已将我的网站包含在他们的应用程序中 我的问题是 所有 HTTP 请求都会自动重定向到 HTTPS 该网站运行良好 但 S
  • HtmlAgilityPack.HtmlDocument Cookie

    这与脚本内 可能在脚本标签内 设置的cookie有关 System Windows Forms HtmlDocument执行这些脚本和cookies集 比如document cookie etc 可以通过其检索Cookies财产 我假设Ht
  • 为什么随机访问迭代器的算术运算符接受/返回 int 而不是 size_t?

    由于大多数操作都在std vector要求 返回size t 这就是我用于索引的类型 但现在我已经启用了所有编译器警告来修复一些我知道的签名 未签名转换问题 这条消息让我感到惊讶 警告 C4365 参数 从 size t 转换为 w64 i
  • Java的notify()在wait()之前运行?

    public class ThreadA public static void main String args ThreadB b new ThreadB b start synchronized b try System out pri