Java线程的等待和通知方法

2024-04-29

我正在学习 OCJP,现在我在“线程”章节,我有一些关于等待和通知方法的问题。我想我明白这里发生了什么,但我只是想确保我走在正确的道路上。我编写了这段代码作为示例:

package threads;

public class Main {

    static Object lock = new Object();

    public static void main(String[] args) {
        new Main().new FirstThread().start();
        new Main().new SecondThread().start();
    }

    class FirstThread extends Thread {
        public void run() {
            synchronized (lock) {
                lock.notify();
                System.out.println("I've entered in FirstThread");
            }
        }
    }
    class SecondThread extends Thread {
        public void run() {
            synchronized (lock) {
                try {
                    lock.wait();
                    System.out.println("I'm in the second thread");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

在此示例中,控制台输出为I've entered in FirstThread,因为第一个线程启动,调用了notify()方法,然后第二个线程启动,调用了wait()方法,并没有打印String“我在第二个线程”。

下一个场景是我颠倒位置new Main().new FirstThread().start(); and new Main().new SecondThread().start();输出是

I've entered in FirstThread
I'm in the second thread

因为第二个线程启动,调用了wait()方法,然后第一个线程启动,调用了notify()方法,控制台打印I've entered in FirstThread,等待被释放并且I'm in the second thread打印在控制台中。

发生这种情况是因为计算机速度太快并且线程按顺序运行吗?理论上,我认为可以首先调用第二个 start() 方法,是吗?

我的最后一个问题是为什么锁对象必须是静态的,因为如果我删除静态修饰符,输出总是I've entered in FirstThread?

我知道静态字段是在类加载时在JVM中加载的,但是我无法理解锁定Object的逻辑。


线程按顺序启动,理论上线程 1 将在线程 2 之前执行,尽管它是不保证(很确定在这个简单的情况下它会是一致的,因为没有真实或模拟的偶然延迟)。

这就是为什么当线程 2 稍微提前启动时,它有机会等待随后(由线程 1)通知的锁,而不是永远等待已经通知过一次的锁(因此,不打印)。

On the static lock Object: 你正在绑定你的[First/Second]Thread嵌套类到实例 of Main,因此如果您希望它们在同一锁上同步,则该锁必须是两者共用的。

如果它是一个实例对象,您的线程将在不同的锁上访问和同步,就像您的线程一样new Main()...习语会得到两个实例Main以及随后的两个实例lock.

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

Java线程的等待和通知方法 的相关文章

随机推荐

  • 客户端检索 Google 联系人图片

    我正在使用 Google JavaScript API 在网络应用程序中获取 Google 联系人 并且我想检索他们的照片 我正在做这样的事情 大大简化 var token let s admit this is available alr
  • 在Windows中比较2个二进制文件的工具[关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我需要一个工具来比较两个二进制文件 文件相当大 我在互联网上找到的一些免费软件或试用工具不方便用于大文件
  • 将 NetCDF 转换为 GRIB2

    我知道有这样的软件wgrib2 http www cpc ncep noaa gov products wesley wgrib2 这会将文件转换为grib and grib2格式化为NetCDF文件 但我需要走另一条路 来自NetCDF
  • GNU FORTH 有编辑器吗?

    第 3 章开始前进 http www forth com starting forth says 现在您已经将一个块设置为 当前 您只需输入单词即可列出它L 不像LIST L不希望以块号开头 相反 它列出了当前块 当我跑步时180 LIST
  • Android Proguard - 保留所有第 3 方库是最佳实践吗?

    我正在为使用第 3 方库的应用程序配置 Proguard 包含以下行是否是 最佳实践 为了避免将来难以发现的错误 keep class 3rd party lib name 对于每个没有来自其开发人员的特定 Proguard 指令的第 3
  • 从 JQuery 中的元素获取点击处理程序

    如何获取对 JQuery 中元素的单击处理程序的引用 这是我正在尝试做的事情 存储点击处理程序 更改下一次单击的单击处理程序 恢复原始点击处理程序 var originalClick settings currentTarget click
  • 将多个前缀行过滤器设置为扫描仪 hbase java

    我想创建一台扫描仪 它可以为我提供带有 2 个前缀过滤器的结果例如 我想要其键以字符串 x 开头或以字符串 y 开头的所有行 目前我知道只能使用一个前缀 方法如下 scan setRowPrefixFilter prefixFiltet 在
  • 通过 URL 中的 ID 进行 RestKit 关系映射

    假设我有一个 APIusers 1 items返回一个列表items为了userID 为 1 假设API响应如下 items id 1 description Some item 请注意 响应不包含user id用于关系映射 RestKit
  • 提高我的脚本性能 Google Sheets 脚本

    我创建了一个函数 每当我运行 AppendRow 脚本时 AY 列中没有点 的每一行 包含我想要的每个信息 列的数组从该表将被转移到我的主表 其中有13k rows atm 通常 每天大约有 20 40 行被粘贴到第一个工作表中 此脚本会自
  • mcdropdown 的替代方案

    我正在构建一个自动完成下拉列表 用户可以从多个级别的类别中进行选择 在该网站的先前版本中 我们使用http www givainc com labs mcdropdown jquery plugin htm http www givainc
  • 如何减少 Ionic Cordova 项目启动持续时间?

    我做了一个离子科尔多瓦项目 但发布到Android手机后 根据手机类型 我们的程序持续时间约为 10 20 秒 当我搜索这个问题时 人们说这是因为 启动画面持续时间 离子启动画面未加载 https stackoverflow com que
  • 如何使用p:ajax按顺序更新多个组件

    我正在尝试呈现以下 JSF 页面
  • HoloEverywhere 的正确使用方法是什么

    我正在尝试使用开发分支HoloEverywhere 库添加到我的应用程序中 我知道这仍处于开发阶段 但演示似乎工作正常 所以我尝试一下 I put android theme style Holo Theme Sherlock Light
  • Java Thread.sleep 最短时间[重复]

    这个问题在这里已经有答案了 The TimeUnit sleep 长超时 http docs oracle com javase 8 docs api java util concurrent TimeUnit html sleep lon
  • 简化 Django 中的表单提交

    我在 Django 中有一个表单 用户可以在其中以单个表单提交文件 图像 文本 如下所示
  • git Cherry-pick 和 git show 有什么区别?补丁-p1?

    我遇到了一种情况git cherry pick X会产生一些冲突 但也会创建额外的插入 当使用git diff 然后我重新跑了git show X gt my patch 然后做了patch p1 lt my patch在我的树上 我得到了
  • 如何使用 QWebElement 设置 input(type="file") 的值?

    我正在尝试将照片上传到vk com https vk com using QtWebKit https qt project org doc qt 4 8 qtwebkit html模块 我面临的问题是无法正确填写input type fi
  • 在 SQL Server 中以编程方式创建数据库

    如何以编程方式创建数据库以及执行此操作所需的最少信息是什么 Please没有 SQL Server 管理对象 API 建议 您可以使用SQL Server 管理对象 API http msdn microsoft com en us lib
  • jQuery UI:DatePicker,仅选择今天到过去的日期

    我在 jQuery UI 核心中使用 datePicker 我需要一个只能选择从过去一直到今天的日期的日期选择器 是否有捷径可寻 请注意 我使用的是 UI 核心 而不是 DatePicker 插件 我的 jQuery 调用 function
  • Java线程的等待和通知方法

    我正在学习 OCJP 现在我在 线程 章节 我有一些关于等待和通知方法的问题 我想我明白这里发生了什么 但我只是想确保我走在正确的道路上 我编写了这段代码作为示例 package threads public class Main stat