Thread.join 和 Synchronized 有什么区别?

2024-01-30

我很困惑何时使用Thread.join()以及何时使用synchronization在多线程应用程序中。

根据我的说法,它们都阻塞或等待其他线程完成执行。
此示例必须按顺序模式依次输出 10 个 A、10 个 B 和 10 个 C,如下所示:

1  : A
2  : A
3  : A
4  : A
5  : A
6  : A
7  : A
8  : A
9  : A
10 : A
1  : B
2  : B
3  : B
4  : B
5  : B
6  : B
7  : B
8  : B
9  : B
10 : B
1  : C
2  : C
3  : C
4  : C
5  : C
6  : C
7  : C
8  : C
9  : C
10 : C
----ProGraM ENDS----

示例从这里开始

class SyncTest extends Thread 
{   
    StringBuffer sb;

    public SyncTest(StringBuffer sb) 
    {
        this.sb = sb;   
    }

    public void run()
    {
        synchronized(sb) 
        {
            for(int i=1;i<=10;i++){
                System.out.println(i+" : "+sb.charAt(0));
            }
            sb.setCharAt(0, (char) (sb.charAt(0)+1));
        }
    }

    public static void main(String [] args) throws InterruptedException
    {
        StringBuffer sb = new StringBuffer("A");
        Thread t1=new SyncTest(sb);
        Thread t2=new SyncTest(sb);
        Thread t3=new SyncTest(sb);

        t1.start();

        t2.start();

        t3.start();

        Thread.sleep(1000);

        System.out.println("----ProGraM ENDS----");
    }
}

这里,输出结果是按顺序依次是 10 个 A、10 个 B、10 个 C。但我也可以使用Thread.join代替synchronized块以获得相同的输出,如下所示:

public void run()
    {
        //removed synchronized statement...

            for(int i=1;i<=10;i++){
                System.out.println(i+" : "+sb.charAt(0));
            }
            sb.setCharAt(0, (char) (sb.charAt(0)+1));

    }

    public static void main(String [] args) throws InterruptedException
    {
        StringBuffer sb = new StringBuffer("A");
        Thread t1=new SyncTest(sb);
        Thread t2=new SyncTest(sb);
        Thread t3=new SyncTest(sb);

        t1.start();
        t1.join();
        t2.start(); // wait for t1 to complete
        t2.join();
        t3.start(); // wait for t2 to complete
        t3.join(); 

                     // wait for t3 to complete
        System.out.println("----ProGraM ENDS----");
    }

任何人都可以消除我对这两种技术的使用的困惑,即何时使用Thread.join以及何时使用synchronizationJava 上的多线程。


Thread.join()等待线程完全完成,而synchronizedblock可以用来防止两个线程同时执行同一段代码。

一般来说,很难建议何时使用其中一种,因为它们有不同的用途。很少找到一个示例,例如您的代码,其中两者之间的差异很小。

话虽如此,在您的第一个示例中,不能保证输出将按字母顺序排列。你无法确定哪个线程会到达synchronized先阻止。所以在这个特殊情况下,join()是最合适的。

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

Thread.join 和 Synchronized 有什么区别? 的相关文章

随机推荐

  • 如何在 Jetpack Compose 中用 TextField 替换部分文本?

    例如我有这个 TAKE O take those lips away That so sweetly were forsworn And those eyes the break of day Lights that do mislead
  • 在 RSpec 中测试模块

    在 RSpec 中测试模块的最佳实践是什么 我有一些模块包含在几个模型中 现在我只是对每个模型进行重复测试 几乎没有差异 有办法把它弄干吗 拉德方式 gt let dummy class Class new include ModuleTo
  • FilterOutputStream 的用法

    实际用途是什么FilterOutputStream在Java中 来自javadoc 该类是所有过滤输出流的类的超类 这些流位于已存在的输出流 底层输出流 之上 它用作基本数据接收器 但可能会沿途转换数据或提供附加功能 对我来说 它似乎有相同
  • contentpresenter.content 上的数据触发不起作用

    我正在尝试基于数据触发器切换 contentpresenter 的内容 我想在 contentpresenter content 中显示用户控件 如果我设置了值 否则我需要显示错误消息 但是我的 datatrigger 上的绑定失败指出未找
  • 动态文本框jquery焦点

    我正在创建一个输入类型的动态文本框 如下所示 代码 我无法将焦点设置在输入类型上 var elem document createElement input elem type text elem id txtParent elem set
  • Ember.js数据如何清除数据存储

    我正在尝试 Ember js 并设置了一个小应用程序 用户可以在其中登录和注销 当用户注销时 我想清除数据存储中当前缓存的所有记录 有没有办法做到这一点 或者我必须强制浏览器重新加载页面 我知道这个问题来自 2013 年 但是自从 Embe
  • 如何提高Python 3.6中的SQLite插入性能?

    背景 我想使用 Python 向 SQLite 插入 100 万条记录 我尝试了很多方法来改进它 但仍然不太满意 数据库使用 0 23 秒将文件加载到内存 搜索pass如下 但 SQLite 加载并插入文件需要 1 77 秒 环境 英特尔酷
  • SoundCloud API v3 Stream 在 Chrome 中无法工作

    几个月来我一直试图让它发挥作用 但仍然不起作用 它在除 Google Chrome 之外的所有浏览器中都能正常工作 问题是音频无法在 Chrome 中传输 这是一个最基本的 JS 小提琴示例 https jsfiddle net sq23u
  • ExtJS 4 应用程序登录和身份验证及权限

    我正在使用新推荐的应用程序结构在 Ext JS 4 上开发一个 Web 应用程序 因此我需要实施一个身份验证和权限系统 到目前为止的想法 服务器负责保证用户的角色和权限 ExtJS前端必须根据权限和角色进行更改 我使用卡片布局 第一个选项卡
  • 使用 Nodejs 面对 api

    我正在使用使用 Node js 的 Azure Face api 下面是代码 然而 我想使用本地图像并发布它 而不是托管一些图像 我尝试了不同的选项 但它无法识别图像格式或无效的图像网址 以下是我尝试过的事情 1 var stream fs
  • 知道hadoop中数据节点的磁盘空间吗?

    有没有一种方法或任何命令可以让我了解每个数据节点的磁盘空间或总集群磁盘空间 我尝试了命令 dfs du h 但似乎我没有权限对许多目录执行它 因此无法获取实际的磁盘空间 From UI http namenode 50070 dfsheal
  • 为什么在 JpaTransactionManager 中使用 jpadialect

    我正在从 Spring in Action 学习 spring 3 0 那里讨论了在 JpaTranactionManager 中使用 jpadialect 的重要性
  • 使用 !source 的 gitconfig 别名不起作用 (zsh)

    我有一个像这样的 gitconfig alias l source githelpers pretty git log 当我运行它时 我得到这个 desktop git l source githelpers pretty git log
  • 设置 geopandas 地图的中心

    我可以用 geopandas 绘制世界地图 world geopandas read file geopandas datasets get path naturalearth lowres fig ax plt subplots worl
  • 使用 opencart 获取多商店设置的商店 ID

    我们设置了多个商店 我想稍微更改每个商店的模板 我仔细查看了已经存在的代码并发现了这些 this gt config gt get config store id this gt load gt model setting store re
  • 如何获取 Windows 版的 python-dev?

    我们正在尝试安装 PIL 并收到错误 error command gcc failed with exit status 1 许多类似的问题 包括这个 安装 Reportlab 错误 命令 gcc 失败 退出状态为 1 https stac
  • 如何在“

    余烬绑定数据属性指南 https guides emberjs com v2 10 0 templates binding element attributes 说 如果您使用带有布尔值的数据绑定 它将添加或删除指定的属性 我正在尝试使用此
  • 哪个系统调用返回连接到 Linux 系统的设备列表?

    我正在尝试编写一个 C Java 程序 它将显示连接到系统的设备列表 非常感谢在这方面的任何帮助 lsusb http www cyberciti biz faq linux how do i list all usb devices 命令
  • iOS EXC_BAD_ACCESS:如何调试?

    我收到 EXC BAD ACCESS 我知道这通常意味着什么 尝试访问 不再 的对象是最可能的原因 那么 我在哪里可以找到它 我在网上看了很多帖子 他们都说 方案中 启用 NSZombie 现在 当我运行调试器时 我应该查看什么 我看不出有
  • Thread.join 和 Synchronized 有什么区别?

    我很困惑何时使用Thread join 以及何时使用synchronization在多线程应用程序中 根据我的说法 它们都阻塞或等待其他线程完成执行 此示例必须按顺序模式依次输出 10 个 A 10 个 B 和 10 个 C 如下所示 1