多线程之间共享数据的方式探讨

2023-10-29

多线程之间共享数据的方式探讨

方式一:代码一致

  • 如果每个线程执行的代码相同,可以用一个 Runnable 对象,这个 Runnable 对象中存放那个共享数据(卖票系统可以这样做)。
public class MultiThreadShareData {
    public static void main(String[] args) {
        MyShareData shareData=new MyShareData();
        //放入不同的线程中
        new Thread(shareData).start();

        new Thread(shareData).start();

    }
}

class MyShareData implements Runnable {
        // 共享的数据
        private int count = 100;

        @Override
        public void run() {
            while (count > 0) {
                synchronized (this) {
                    if (count > 0) {
                        count--;
                        System.out.println(Thread.currentThread().getName() + " 减了1,count还剩:" + count);
                    }

                }

            }
        }
    }

 

方式二:代码不一致

  • 如果每个线程执行的代码不同时,就需要不同的 Runnable 对象:

a. 将共享数据封装在一个对象中,然后将这个对象逐一传递给各个 Runnable 对象,每个线程对共享数据操作的方法也分配到这个对象中,这样容易实现针对该数据进行的各个操作的互斥通信。

public class MultiThreadShareData {

    private int shareData=0;

    public static void main(String[] args) {
        ShareData data = new ShareData();

        new Thread(new MyRunnable1(data)).start();

        new Thread(new MyRunnable2(data)).start();
    }

}

class MyRunnable1 implements Runnable{

    private ShareData data;

    public MyRunnable1(ShareData data){
        this.data=data;
    }

    @Override
    public void run() {
        for(int i=0;i<100;i++){
            //对数据进行增加
            this.data.increment();
        }
    }
}

class MyRunnable2 implements Runnable{

    private ShareData data;

    public MyRunnable2(ShareData data){
        this.data=data;
    }

    @Override
    public void run() {
        for(int i=0;i<100;i++){
            //对数据进行减少
            this.data.decrement();
        }
    }
}

/**
 将共享的数据封装成一个类
*/
class ShareData{
    //共享数据
    private int j=0;

    public synchronized void increment(){
        this.j++;
        System.out.println(Thread.currentThread().getName()+":j增加了1后j="+j);
    }

    public synchronized void decrement() {
        this.j--;
        System.out.println(Thread.currentThread().getName()+":j减少了1后j="+j);
    }
    public int getJ() {
        return j;
    }
}

b. 将 Runnable 对象作为某一个类的内部类,共享数据作为这个外部类的成员变量,每个线程对共享数据的操作方法也分配到外部类中,实现共享数据的互斥和通信操作,作为内部类的各个 Runnable 对象调用外部类的这些方法。

public class MultiThreadShareData {

    private int shareData=0;

    public static void main(String[] args) {
        MultiThreadShareData m=new MultiThreadShareData();
        //初始化Runnable对象
        MyRunnable1 myRunnable1 = m.new MyRunnable1();
        MyRunnable2 myRunnable2=m.new MyRunnable2();

        //开启线程
        new Thread(myRunnable1).start();

        new Thread(myRunnable2).start();
    }

    private synchronized void increment(){
        this.shareData++;
        System.out.println(Thread.currentThread().getName()+":shareData增加了1后shareData="+shareData);
    }

    private synchronized void decrement() {
        this.shareData--;
        System.out.println(Thread.currentThread().getName()+":shareData减少了1后shareData="+shareData);
    }

    /**
     * 作为内部类的Runnable对象
     */
    class MyRunnable1 implements Runnable{

        @Override
        public void run() {
            for(int i=0;i<100;i++){
                increment();
            }
        }
    }

    class MyRunnable2 implements Runnable{

        @Override
        public void run() {
            for(int i=0;i<100;i++){
                decrement();
            }
        }
    }
}

c. 以上两种方法的组合:将共享数据封装到一个对象中,每个线程对共享数据的操作方法也分配到对象中,对象作为外部类的成员变量或方法中的局部变量,每个线程的 Runnable 作为成员内部类或局部内部类。

 public class MultiThreadShareData {
   public static void main(String[] args) {

       ShareData data = new ShareData();

       new Thread(()->{
           for(int i=0;i<100;i++){
               data.increment();
           }
       }).start();

       new Thread(()->{
           for (int j=0;j<100;j++) {
               data.decrement();
           }
       }).start();
   }

}

/**
封装共享数据的对象
*/
class ShareData{
   //共享数据
   private int j=0;

   /**
    对共享数据进行操作的方法
   */
   public synchronized void increment(){
       this.j++;
       System.out.println(Thread.currentThread().getName()+":j增加了1后j="+j);
   }

   public synchronized void decrement() {
       this.j--;
       System.out.println(Thread.currentThread().getName()+":j减少了1后j="+j);
   }

   public int getJ() {
       return j;
   }
}

总之, 要同步互斥的几段代码最好放在几个独立的方法中,这些方法再放入一个类中,这样比较容易实现它们之间的同步互斥和通信。

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

多线程之间共享数据的方式探讨 的相关文章

  • hbase小版本升级

    备份原版本 cd opt hbase cp pr bin bin bak cp pr lib lib bak cp pr hbase webapps hbase webapps bak 停止hbase opt hbase bin stop
  • 前端报403错误的可能原因

    1 跨域问题 2 请求服务器路径问题
  • Java 单元测试_JUnit 框架

    1 单元测试简介 单元测试就是针对最小的功能单元编写测试代码 Java程序最小的功能单元是方法 因此 对Java程序进行单元测试就是针对单个Java方法的测试 1 1 JUnit JUnit 是一套测试框架 JUnit是一个开源的Java语
  • UE4_蓝图室内功能交互

    玩家角色移动 玩家旋转 点击开关门效果 方式二 优化完整版开关门效果 点击开关灯效果 键盘开关灯效果及更改颜色 进入区域开关灯效果 电视播放视频 效果一 单击鼠标播放电视视频 创建MediaPlayer的方法 播放效果3 完整版 窗帘打开和
  • java中文转unicode码

    http open weibo com wiki index php Location get addr转载地址 http www iteye com topic 471901 http blog csdn net zhengjianqi
  • Ubuntu20.0.0安装docker容器

    一 Docker介绍 Docker 是一个开源的应用容器引擎 基于 Go 语言 并遵从 Apache2 0 协议开源 Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级 可移植的容器中 然后发布到任何流行的 Linux 机器上
  • 用友出纳通服务器修改系统日期,用友T3软件出纳通里面如何修改账户的建账日...

    用友T3软件出纳通里面如何修改账户的建账日以下文字资料是由 历史新知网www lishixinzhi com 小编为大家搜集整理后发布的内容 让我们赶快一起来看一下吧 用友T3软件出纳通里面如何修改账户的建账日 启用之后就无法修改了 除非你
  • 大众点评数据

    数据名称 大众点评POI数据 数据年份 2022最新版 数据量 4000w 数据范围 全国范围 数据变量 id 店铺id 店铺名称 店铺位置 店铺区县 店铺商圈 小类 大类 城市id 城市名 是否外卖 均价 人气 分数 星级 状态 电话 位
  • CMake + VTK

    编译VTK本身没有太多的坑 我使用的是VS2015 x64 Native Tools Command Prompt 基本上就是典型的 cmake G Visual Studio 14 Win64 即可 使用编译后的结果时主要是要注意VTK
  • 数据库入门书籍推荐

    数据库入门书籍推荐 书籍书籍 数据库系统概论 内容简介 数据库理论入门必读 本书系统全面的阐述了数据库系统的基础理论 基本技术和基本方法 我国第一部系统阐述数据库原理 技术和方法的教材 适时反映数据库领域的新成果和应用新方向 内容丰富 概念
  • QLineEdit的信号与槽用法

    QLineEdit一共有6个信号函数 并不多 很好理解 1 void cursorPositionChanged intold intnew 当鼠标移动时发出此信号 old为先前的位置 new为新位置 在文本框中输入一个字符 光标移动一格
  • 封神台靶场-第四章

    第四章 为了更多的权限 Tips 1 存储型Xss 2 flag在cookie里 格式为zkz xss bot 每10秒访问一次页面 3 自建Xss平台源码 http www zkaq org t 99 html 登陆后根据提示要进行存储型
  • 程序性能

    文章目录 1 程序性能 1 1 空间效率 1 2 时间效率 1 3 f n 程序性能表示 程序性能包括两个部分 空间效率和时间效率 1 程序性能 1 1 空间效率 一个运行的程序所占用的内存 1 栈 函数调用时操作系统自动分配的内存 函数调
  • commitlint配置

    聊一下如何配置commit lint 其实这个问题一直困扰我很久 看了好多文章 都无济于事今天狠下心来终于解决 废话不多说 先上代码 最后阐述原因 因为有的小伙伴就是想找到解决问题办法 至于原因不太关心 注意 npm 版本大于 7 安装 h
  • 网站服务器被攻击的形式,服务器被攻击的不同表现类型以及应对策略

    服务器被攻击的不同表现类型以及应对策略 许多网站站长都遇到过网络服务器被攻击的状况 被攻击之后也大多数都只有束手待毙 由于大伙儿广泛对攻击不足掌握 很多人把多很多的攻击和防御力挂在嘴上 却压根不清楚网络服务器是怎么被攻击的 更不要说怎样应对
  • MyBatis-Plus-自定义模板-生成代码

    MyBatis Plus代码生成器所需jar包
  • windows无法访问FTP服务器的各种报错解决

    本文转载自windows无法访问FTP服务器的各种报错解决 对于windows无法访问FTP服务 原因有很多 但首先要保证 你的服务配置无误 用户有访问资源的权限 防火墙拦截 服务器防火墙通行了 忽略了客户端的防火墙可不行 对于不信任的连接

随机推荐

  • special effects - 樱花飘落背景特效

    樱花飘落背景特效 一 效果图 二 实现代码 一 效果图 二 实现代码
  • VPS是虚拟专用服务器,部署VPS包括以下步骤

    VPS是虚拟专用服务器 部署VPS包括以下步骤 购买VPS主机 选择可靠的云服务提供商 如亚马逊AWS 谷歌云 腾讯云或阿里云 并注册账户和创建VPS实例 为了确保您的应用程序在运行过程中具有快速的性能和可靠的服务级别协议 请评估不同主机计
  • Intel TBB简介及在Windows7 VS2013上源码的编译过程

    Intel TBB Intel Threading Building Blocks 是Intel线程构建块开源库 它的License是Apache 2 0 Intel TBB是一种用于并行编程的基于C 语言的框架 它是一套C 模板库 它提供
  • 【http协议】超详细介绍

    文章目录 一 协议 1 1 Method 1 1 1 HEAD 1 2 Status 1 3 Http Head Http 头 1 3 1 Http Request Body 1 3 1 1 Content Type 1 3 1 2 miu
  • 浅谈Web用户体验(二)

    在所有网页或浏览器的GUI中我最喜欢的是google的用户体验效果 平时我们只把它作为搜索工具 从没仔细欣赏过它的设计细节 有篇博客对google的用户体验总结的非常好 google的设计一向以简单著称 让页面清爽优雅地呈现 一方面减少页面
  • Notepad++找回缓存的内容

    场景 在使用Notepad 的时候 有一个非常方便的自动保存功能 也就是你在新建一个文档后 输入你的内容 在你没有手动保存前 Notepad 会帮你保存当前内容 当你没有保存就退出Notepad 下次进来Notepad 会自动把你上次编辑的
  • 图像处理之三角法图像二值化

    图像处理之三角法图像二值化 三角法求阈值最早见于Zack的论文 Automatic measurement of sister chromatid exchange frequency 主要是用于染色体的研究 该方法是使用直方图数据 基于纯
  • mybatis常见的报错点总结

    1 invalid comparison java util Date and java lang String 错误代码 正确代码 错误原因 将日期格式和字符串进行了比较 2 NumberFormatException 错误代码 正确代码
  • IDEA项目编写到一半 突然Install报错Cannot resolve org.apache.maven.plugins:maven-compiler-plugin:X.X.X

    描述 是一次很蛇皮的踩坑经历 原因很简单 但是太容易中招了 简单记录一下 项目没有做热部署 添加完一个CRUD的接口后 重启项目测试 突然就报错了 mvn clear install也没用 Cannot resolve org apache
  • 笔试真题解析

    恭喜发现宝藏 搜索公众号 TechGuide 回复公司名 解锁更多新鲜好文和互联网大厂的笔经面经 作者 TechGuide 全网同名 订阅专栏 进阶版 2023最新大厂笔试真题 题解 不容错过的宝藏资源 第一题 服务器能耗统计 100分 题
  • Fine BI、Smart BI、永洪BI、瓴羊Quick BI这些国产BI工具,都擅长哪些功能?

    近几年 随着国内大数据的火热 商业智能BI工具市场也迎来了大爆发 市面上涌现出了各种各样的BI工具 让很多企业在选择BI工具的时候遇上了 选择困难症 在最初 大多数企业都会选择Tableau 微软Power BI等外国公司的BI工具 然而
  • ARouter(七) 依赖注入

    当你从FirstActivity跳到SecondActivity 有时需要把参数值放在intent里面传过去 ARouter的依赖注入会帮你在SecondActivity里面的属性直接赋好参数值 当然需要你事先在SecondActivity
  • 西瓜书-3.9,3.10理解过程-线性模型

    许多人对3 9公式不理解 其实 min右侧只是用矩阵的形式表示了均方差的概念 大家可以结合矩阵的乘法运算举个例子试试 argmin表示右侧式子最小时w取得的值 我们的目标就是求出这个向量w 需要注意的是 实际问题中 我们的样例数可能很少 而
  • GPU基础与CUDA编程入门

    文章目录 一 GPU和CPU的区别 GPU 高吞吐量导向设计 CPU 低延迟导向设计 GPU适合什么场景 什么是Prefetch 二 CUDA与OpenCL 三 CUDA编程并行计算整体流程 内存模型 线程块 网格Grid 并行线程块组合
  • 【Python解题1】PAT 乙级1055 集体照(详解)测试点345错误原因分析

    题目传送门 语言 python3 9 编译工具 pycharm 社区版 输入样例 10 3 Tom 188 Mike 170 Eva 168 Tim 160 Joe 190 Ann 168 Bob 175 Nick 186 Amy 160
  • 《C++ System Programming Cookbook》第二章读书笔记

    第二章 C 重要知识点回顾 C primitive types 原生数据类型 char int float double wchar t bool void nullptr t 可用numeraic limits检查范围 sizeof检查大
  • 【翻译】如何在你的IT转型中浪费数以亿计的资金

    你担任范德雷工业公司的首席执行官已经有几年时间了 这是一家在运输领域存在了几十年的巨无霸 真正的战略 你真的希望股价能尽快上涨 这样你就可以在命运之轮转动之前 在最佳的时间点卖掉你的股票 而董事会也不可避免地要把你赶走 你已经厌倦了蒲公英
  • 甘特图排程组件开发(TsyGantt)

    甘特图在Project2000中 很是好用 可是我想在项目开发中还要买了MS的Project2000的版权 所以索性自己开发一套相关的组件
  • 【JavaWeb_Part05】JDBC?弱爆了,看看轻量级的 Mybatis FreeStyle

    开篇 上篇文章我们已经讲了 Mybatis 的入门以及简单的对单表进行增删改查 那么今天我们就来讲一下使用 mybatis 开发dao的两种方式以及 mysql 比较厉害的动态 sql 利用 mybatis 开发 DAO 1 原始的方式开发
  • 多线程之间共享数据的方式探讨

    多线程之间共享数据的方式探讨 方式一 代码一致 如果每个线程执行的代码相同 可以用一个 Runnable 对象 这个 Runnable 对象中存放那个共享数据 卖票系统可以这样做 public class MultiThreadShareD