Java零基础之多线程篇:线程同步

news2024/11/16 13:48:13

哈喽,各位小伙伴们,你们好呀,我是喵手。运营社区:C站/掘金/腾讯云;欢迎大家常来逛逛

  今天我要给大家分享一些自己日常学习到的一些知识点,并以文字的形式跟大家一起交流,互相学习,一个人虽可以走的更快,但一群人可以走的更远。

  我是一名后端开发爱好者,工作日常接触到最多的就是Java语言啦,所以我都尽量抽业余时间把自己所学到所会的,通过文章的形式进行输出,希望以这种方式帮助到更多的初学者或者想入门的小伙伴们,同时也能对自己的技术进行沉淀,加以复盘,查缺补漏。

小伙伴们在批阅的过程中,如果觉得文章不错,欢迎点赞、收藏、关注哦。三连即是对作者我写作道路上最好的鼓励与支持!

前言

  在上几期中,我们学习了多线程的创建、生命周期及如何控制线程,而此期我们要来学习一下如何进行线程同步。我们都知道,在并发编程中,多线程的使用已经成为一种常见的解决方案。然而,当多个线程同时访问共享资源时,可能会导致数据不一致的问题。为了解决这个问题,我们需要使用线程同步机制来确保多个线程能够有序地访问和修改共享资源。

摘要

  本文将介绍Java中的线程同步机制。我们将使用synchronized关键字来保证同一时间只有一个线程能够执行特定的代码块或方法。我们还将讨论线程同步的应用场景、优缺点以及提供具体的Java代码测试用例来说明其效果。不知道这个关键字大家可有在其他的场景中使用过?有的同学欢迎下方评论区留言分享。

简介

  Java提供了多种线程同步的机制,其中最常用的是通过synchronized关键字来实现。在多个线程访问共享资源时,我们可以使用synchronized来标记关键代码块或方法,以确保只有一个线程能够执行该代码块或方法。

应用场景案例

线程同步机制在以下情况下特别有用:

  • 多个线程需要同时访问和修改共享资源,例如数据库连接池、文件读写等。
  • 需要保证某个操作的原子性,例如银行转账操作。

优缺点分析

线程同步机制的优点包括:

  • 避免了多个线程同时访问共享资源导致的数据不一致问题。
  • 确保了某个操作的原子性,避免了出现意外的结果。

然而,线程同步也有一些缺点:

  • 会降低程序的执行效率,因为同一时间只有一个线程能够执行同步代码块或方法。
  • 如果使用不当,可能会导致死锁或活锁等问题。

  因此,在使用线程同步机制时,我们需要仔细考虑其适用性以及潜在的性能和安全问题,能够使其在可控的情况下进行,而不是一发而不可收拾。

类代码方法介绍

  • increment()方法:使用synchronized关键字修饰的方法,用于增加count变量的值。
  • getCount()方法:使用synchronized关键字修饰的方法,用于获取count变量的值。

测试用例

  我们通过创建两个线程来测试线程同步的效果,每个线程都会调用 increment()方法来增加count变量的值。在最后,我们输出count的值来验证线程同步的正确性。

  下面我给是一个简单的示例代码,演示了如何使用synchronized关键字来实现线程同步:

测试代码展示

package com.example.javase.ms.threadDemo.day4;

/**
 * @Author ms
 * @Date 2024-04-12 22:47
 */
public class ThreadSynchronizationExample {
    private int count = 0;

    public synchronized void increment() {
        count++;
    }

    public synchronized int getCount() {
        return count;
    }

    public static void main(String[] args) {
        ThreadSynchronizationExample example = new ThreadSynchronizationExample();

        Thread thread1 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                example.increment();
            }
        });

        Thread thread2 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                example.increment();
            }
        });

        thread1.start();
        thread2.start();

        try {
            thread1.join();
            thread2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("Count: " + example.getCount());
    }
}

  在上面的代码中,我们定义了一个ThreadSynchronizationExample类,其中包含一个私有的count变量。我们使用synchronized关键字修饰了increment()方法和getCount()方法,以确保在同一时间只有一个线程能够执行这些方法。在main()方法中,我们创建了两个线程并启动它们,每个线程都会调用increment()方法来增加count变量的值。最后,我们输出count的值来验证线程同步的效果。

测试结果展示

  当程序运行时,thread1thread2将并发地尝试更新count变量。由于incrementgetCount方法都是同步的,这保证了对count变量的访问是线程安全的。最终,count变量的值应该是2000(每个线程递增1000次)。

  根据如上测试用例,这里我们本地执行一下,结果展示如下:可以判断下输出的结果是否与预期结果一致!

在这里插入图片描述

测试代码分析

  根据如上代码作出解析,以便于同学们更好的理解,分析如下:

  这段Java代码展示了一个简单的线程同步示例。在这个例子中,我们有一个ThreadSynchronizationExample类,它包含一个共享资源count,以及两个线程thread1thread2,它们都试图更新这个共享资源。

类成员和方法解析

  • count变量:这是一个共享资源,用于记录increment方法被调用的次数。它被声明为private,意味着只能在这个类的内部访问和修改。
  • increment方法:这是一个同步方法,用于递增count变量的值。通过synchronized关键字,确保每次只有一个线程能够执行这个方法,从而避免了并发访问时的竞态条件。
  • getCount方法:这也是一个同步方法,用于返回当前count变量的值。由于它访问了共享资源count,所以也需要同步。

main方法解析

  • 创建ThreadSynchronizationExample实例:在主线程中创建了一个ThreadSynchronizationExample类的实例。
  • 创建并启动线程:创建了两个线程thread1thread2,它们都执行一个lambda表达式,该表达式调用increment方法1000次。
  • 等待线程完成:通过调用thread1.join()thread2.join(),主线程等待这两个线程完成它们的执行。这是通过join()方法实现的,它会阻塞主线程直到对应的线程结束。
  • 捕获中断异常:在等待线程完成的过程中,如果当前线程被中断,InterruptedException将被抛出。在catch块中处理这个异常,打印堆栈跟踪信息。
  • 输出最终计数值:一旦所有线程都完成了它们的执行,主线程将输出count变量的最终值。

线程同步的重要性

  线程同步是多线程编程中的一个重要概念。它确保了在多个线程并发访问共享资源时,资源不会被不一致地修改,从而避免了竞态条件和其他并发问题。在这个例子中,通过使用synchronized关键字,我们确保了对count变量的访问是原子性的,即每次只有一个线程能够执行increment方法。这样可以确保count变量的值是正确的,反映了所有线程对它的更新。

全文小结

  本文介绍了Java中的线程同步机制,以及如何使用synchronized关键字来实现线程同步。我们通过示例代码演示了线程同步的效果,并讨论了线程同步的应用场景、优缺点以及注意事项。希望读者通过本文的学习能够更好地理解和应用线程同步机制。

总结

  线程同步是为了防止多个线程同时访问共享资源而导致的数据不一致问题。Java提供了多种线程同步的机制,其中最常用的是使用synchronized关键字来实现。通过使用synchronized关键字,我们可以确保同一时间只有一个线程能够执行特定的代码块或方法。然而,线程同步也有一些缺点,例如可能会降低程序的执行效率,并且需要注意避免死锁或活锁等问题。在实际开发中,我们需要根据具体需求来选择合适的线程同步机制,并仔细考虑其适用性和安全性。

… …

文末

好啦,以上就是我这期的全部内容,如果有任何疑问,欢迎下方留言哦,咱们下期见。

… …

学习不分先后,知识不分多少;事无巨细,当以虚心求教;三人行,必有我师焉!!!

wished for you successed !!!


⭐️若喜欢我,就请关注我叭。

⭐️若对您有用,就请点赞叭。

⭐️若有疑问,就请评论留言告诉我叭。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1984118.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java13.0标准之重要特性及用法实例(二十三)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 新书发布&#xff1a;《Android系统多媒体进阶实战》&#x1f680; 优质专栏&#xff1a; Audio工程师进阶系列…

【第三版 系统集成项目管理工程师】第9章 项目管理概论

持续更新。。。。。。。。。。。。。。。 【第三版】第九章 项目管理概论 9.1 PMBOK的发展9.2 项目基本要素9.2.1项目基础 P3041.独特的产品、服务或成果-P3042.临时性工作-P3043.项目驱动变更-P3054.项目创造业务价值-P3055.项目启动背景-P306 9.2.2项目管理 P3069.2.2 项目管…

AQS的ReentrantLock源码

什么是AQS&#xff08;全称AbstractQueuedSynchronizer&#xff09; 代表&#xff1a;重入锁、独占锁/共享锁、公平锁/非公平锁 是JUC包中线程阻塞、阻塞队列、唤醒、尝试获取锁的一个框架 AbstractQueuedSynchronizer是全称&#xff0c;是一个模板模式&#xff0c;一些线程…

深入理解Java的内存管理机制

文章目录 1. 程序计数器 (Program Counter Register)2. Java虚拟机栈 (Java Virtual Machine Stack)3. 本地方法栈 (Native Method Stack)4. 堆 (Heap)a. 年轻代 (Young Generation)b. 老年代 (Old Generation) 5. 方法区 (Method Area)6. 运行时常量池 (Runtime Constant Pool…

magic-api相关应用与配置

目录 项目启动 工具&#xff1a;IDEA 运行项目 关于配置 项目启动 工具&#xff1a;IDEA 新建——》项目——》导入——》运行 运行项目 http://localhost:9999/magic/web/index.htmlhttp://localhost:9999/magic/web/index.html 关于配置 配置多数据源 在线配置多数据…

git版本控制的底层实现

目录 前言 核心概念串讲 底层存储形式探测 本地仓库的详细解析 提交与分支的深入解析 几个问题的深入探讨 前言 Git的重要性 Git是一个开源的版本控制工具&#xff0c;广泛用于编程开发领域。它极大地提高了研发团队的开发协作效率。对于开发者来说&#xff0c;Git是一个…

32-《蝴蝶兰》

蝴蝶兰 蝴蝶兰&#xff08;学名&#xff1a;Phalaenopsis aphrodite Rchb. F.&#xff09;为兰科蝴蝶兰属&#xff0c;原产于亚热带雨林地区&#xff0c;为附生性兰花。蝴蝶兰白色粗大的气根露在叶片周围&#xff0c;除了具有吸收空气中养分的作用外&#xff0c;还有生长和光合…

java之WIFI模块实现文件传输(开源)

AndroidManifest这里要获取到权限,所以要导入: <uses-permission android:name"android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name"android.permission.CHANGE_WIFI_STATE" /> <uses-permission android:name"…

22 - grace数据处理 - 补充 - 泄露误差改正 - Slepian局部谱分析法(二) - Slepian谱分析程序包初始化

22 - grace数据处理 - 补充 - 泄露误差改正 - Slepian局部谱分析法 - Slepian谱分析程序包初始化 0 引言1 slepian程序包配置过程1.1 获取环境配置安装包1.2 执行demo测试是否配置成功2 结语0 引言 上篇提到进行slepian谱分析可以使用美国普林斯顿大学Frederik Simons教授提供的…

Google Chrome 应用商店插件离线导出导入方法(亲测有效)

Google Chrome 浏览器插件&#xff08;也称为扩展程序&#xff09;是一种可以增强浏览器功能的小型软件程序。这些插件可以让用户在浏览器中添加新的功能、定制化界面、自动化任务等。以下是一些常见的 Google Chrome 浏览器插件功能&#xff1a; 功能增强&#xff1a;插件可以…

使用 Pytorch 从头开始​​构建 Transformer

目录 一、说明 二、输入嵌入 2.1 __init__()方法目的 2.2 super() 三、PositionalEncoding 类 四、位置编码的工作原理 4.1 总体过程 4.2 数学公式 五、LayerNormalization 类 5.1 过程描述 5.2 例子 六、FeedForwardBlock 类 6.1 总体描述 6.2 数学公式 七、MultiHeadAttentio…

全球清真食品配料市场规划预测:未来六年CAGR为3.4%

随着全球穆斯林人口的增长和消费能力的提升&#xff0c;清真食品配料作为符合伊斯兰教义的食品添加剂和成分&#xff0c;正逐渐受到更多消费者的青睐。本文旨在通过深度分析清真食品配料行业的各个维度&#xff0c;揭示行业发展趋势和潜在机会。 【市场趋势的演变】 1. 市场规…

AI 生成搞笑段子

段子在我们生活中扮演着极为重要的角色&#xff0c;它不仅能够带给我们欢乐和娱乐&#xff0c;还能够促进交流和拉近人与人之间的距离。通过幽默诙谐的段子&#xff0c;我们可以轻松地化解尴尬和紧张的气氛&#xff0c;让沉闷的场合变得活泼有趣。 而段子手生成器&#xff0c;则…

Flink-DataWorks第一部分:DataWorks(第57天)

系列文章目录 1.1 什么是DataWorks 1.2 功能特性 1.2.1 数据集成&#xff1a;全领域数据汇聚 1.2.3 数据建模&#xff1a;智能数据建模 1.2.4 数据分析&#xff1a;即时快速分析 1.2.5 数据质量&#xff1a;全流程的质量监控 1.2.6 数据地图&#xff1a;统一管理&#xff0c;跟…

数据跨境流动需要注意什么?怎么实现安全合规的跨境传输?

2024年3月22日&#xff0c;《促进和规范数据跨境流动规定》&#xff08;以下简称《数据跨境规定》&#xff09;正式公布并施行。数据跨境流通涉及到隐私保护、安全性和法律合规等多个方面的重要考虑因素。 具体来说&#xff0c;需要注意以下几点&#xff1a; 1、隐私保护&…

农场游戏中的时间管理实例

一、准备工作 在Unity中创建承载日期和时间的文本 二、设置游戏的时间戳 using System.Collections; using System.Collections.Generic; using UnityEngine; //标识这个类可以被序列化 [System.Serializable] public class GameTimestamp {// 游戏时间戳的成员变量public in…

【第三版 系统集成项目管理工程师】第10章 启动过程组

持续更新。。。。。。。。。。。。。。。 【第三版】第十章 启动过程组 10.1 制定项目章程10.1.1 主要输入1.立项管理文件-P3562.协议-P35710.1.2 主要输出1.项目章程-P3572.假设日志-P358练习10.2 识别干系人10.2.1 主要输入1.项目管理计划-P3602.项目文件-P36010.2.2 主要工…

49 mysql 子查询 加 group by 产生的奇怪现象

前言 这里要提到的是一个 之前碰到的一个 很令人诧异的查询, 主要是 和 group 查询有关系 查询如下, 按照常规理解, “select id from t_user_02 where name jerry group by age ” 会返回 两条数据, 然后 整个查询 会查询出两条数据 但是 结果很令人差异, 查询出了 四条…

华为云全域Serverless技术创新:全球首创通用Serverless平台被ACM SIGCOMM录用

华为开发者大会2024&#xff08;HDC 2024&#xff09;在东莞松山湖圆满结束&#xff0c;期间华为云主办的“全域Serverless时代&#xff1a;技术创新引领&#xff0c;赋能行业实践”专题论坛&#xff0c;向广大开发者传递了Serverless领域的前沿思考和实践&#xff0c;现场座无…

CVE-2023-33440详解

一.访问url http://eci-2zef9bcht3lq36hkwyoh.cloudeci1.ichunqiu.com/ 二.目录扫描 http://eci-2zef9bcht3lq36hkwyoh.cloudeci1.ichunqiu.com/ 三.拼接访问/login.php 四.抓包构造数据包 发给repeter 复制过去这几个位置都有空格&#xff0c;要删除掉&#xff0c;Referer和…