一:线程范围内共享数据:

如果每个线程执行的代码相同,可以使用同一个Runnable对象,这个Runnable对象中有那个共享数据,例如,买票系统就可以这么做。

如果每个线程执行的代码不同,这时候需要用不同的Runnable对象,有如下两种方式来实现这些Runnable对象之间的数据共享:

  • 将共享数据封装在另外一个对象中,然后将这个对象逐一传递给各个Runnable对象。每个线程对共享数据的操作方法也分配到那个对象身上去完成,这样容易实现针对该数据进行的各个操作的互斥和通信。
  • 将这些Runnable对象作为某一个类中的内部类,共享数据作为这个外部类中的成员变量,每个线程对共享数据的操作方法也分配给外部类,以便实现对共享数据进行的各个操作的互斥和通信,作为内部类的各个Runnable对象调用外部类的这些方法。

上面两种方式的组合:将共享数据封装在另外一个对象中,每个线程对共享数据的操作方法也分配到那个对象身上去完成,对象作为这个外部类中的成员变量或方法中的局部变量,每个线程的Runnable对象作为外部类中的成员内部类或局部内部类。总之,要同步互斥的几段代码最好是分别放在几个独立的方法中,这些方法再放在同一个类中,这样比较容易实现它们之间的同步互斥和通信。

极端且简单的方式,即在任意一个类中定义一个static的变量,这将被所有线程共享。

下面看着四种方式的实现:

1.如果线程执行的代码相同,多个线程共享同一个runnable对象时,将共享数据放在runnable对象

public class MultiThreadShare {public static void main(String[] args) {ShareData shareData = new ShareData();new Thread(shareData).start();new Thread(shareData).start();}}class ShareData implements Runnable {private int i = 100;@Overridepublic void run() {dec();}public synchronized  void dec() {while (i > 0) {i--;System.out.println(i);}}}


2.如果多个线程执行的代码不同,将共享数据作为外部类的final成员变量,将不同的runnable对象作为内部类主动取数据

public class MultiThreadShare {public static void main(String[] args) {final ShareData shareData = new ShareData();new Thread(new Runnable() {@Overridepublic void run() {for (int i = 0; i < 100; i++) {shareData.dec();}}}).start();new Thread(new Runnable() {@Overridepublic void run() {for (int i = 0; i < 100; i++) {shareData.inc();}}}).start();}}class ShareData {private int j = 100;public synchronized void dec() {j--;System.out.println("--" + j);}public synchronized void inc() {j++;System.out.println("++" + j);}}

3.如果多个线程执行的代码不同,将共享数据封装到一个对象中,将这个对象逐一传递给各个runnable对象

public class MultiThreadShare {public static void main(String[] args) {ShareData data = new ShareData();new Thread(new MyRunable1(data)).start();new Thread(new MyRunable2(data)).start();}
}class MyRunable1 implements Runnable {private ShareData data;public MyRunable1(ShareData data) {this.data = data;}@Overridepublic void run() {for (int i = 0; i < 100; i++) {data.dec();}}}class MyRunable2 implements Runnable {private ShareData data;public MyRunable2(ShareData data) {this.data = data;}@Overridepublic void run() {for (int i = 0; i < 100; i++) {data.inc();}}}class ShareData {private int j = 100;public synchronized void dec() {j--;System.out.println("dec.." + j);}public synchronized void inc() {j++;System.out.println("inc.." + j);}}

4.将数据声明为static的方式

public class MultiThreadShare {private static ShareData data = new ShareData();public static void main(String[] args) {new Thread(new Runnable() {@Overridepublic void run() {for (int i = 0; i < 100; i++) {data.inc();}}}).start();new Thread(new Runnable() {@Overridepublic void run() {for (int i = 0; i < 100; i++) {data.dec();}}}).start();}
}class ShareData {private int j = 100;public synchronized void dec() {j--;System.out.println("--" + j);}public synchronized void inc() {j++;System.out.println("++" + j);}}

参考http://www.cnblogs.com/zhangshiwen/p/5042331.html

多线程学习(四)-线程范围内共享数据相关推荐

  1. Java高并发编程:线程范围内共享数据

    笔记摘要 所谓线程范围内共享数据,即对于相同的程序代码,多个模块在同一个线程中运行时要共享一份数据,而在另外线程中运行时又共享另外一份数据,API中为我们提供了一个操作线程范围内共享数据的类Threa ...

  2. Java实现并发线程中线程范围内共享数据

    ---恢复内容开始--- 利用Map,HashMap键值对的数据结构,实现并发线程中线程范围内数据共享. package cn.qy.heima2;import java.util.HashMap; ...

  3. C#多线程学习(四) 多线程的自动管理(线程池) (转载系列)——继续搜索引擎研究...

    在多线程的程序中,经常会出现两种情况: 一种情况:   应用程序中,线程把大部分的时间花费在等待状态,等待某个事件发生,然后才能给予响应                   这一般使用ThreadPo ...

  4. 【Android 内存优化】Java 内存模型 ( Java 虚拟机内存模型 | 线程私有区 | 共享数据区 | 内存回收算法 | 引用计数 | 可达性分析 )

    文章目录 一. Java 虚拟机内存模型 二. 程序计数器 ( 线程私有区 ) 三. 虚拟机栈 ( 线程私有区 ) 四. 本地方法栈 ( 线程私有区 ) 五. 方法区 ( 共享数据区 ) 1. 方法区 ...

  5. 保护线程间的共享数据

    程序员的自我修养(六):保护线程间的共享数据 多进程和多线程最本质的区别在于共享和隔离的程度不同.对于多进程方式来说,因为隔离程度高,所以程序员很少需要去担心进程空间的数据被破坏:但是并发任务之间共享 ...

  6. Java多线程学习四:共有哪 3 类线程安全问题

    我们在实际开发中经常会遇到线程不安全的情况,那么一共有哪 3 种典型的线程安全问题呢? 运行结果错误: 发布和初始化导致线程安全问题: 活跃性问题. 运行结果错误 来看多线程同时操作一个变量导致的运行 ...

  7. C++多线程快速入门(二)共享数据同步以及数据竞争

    目录 std::unique_lock类模板 仅调用一次 线程局部存储 原子变量 往期内容回顾 std::unique_lock类模板 互斥锁保证了线程间的同步,却将并行操作变成了串行操作,对性能有较 ...

  8. 用matlab做app,2020-02-27 MATLAB App Designer——在用 App 设计工具创建的 App 内共享数据...

    1 访问和更新回调中的 UI 组件内的数据 app.Component.Property 2 获取并设置一个仪表的 Value 属性 x = app.PressureGauge.Value; % Ge ...

  9. Java shared data_Java多个线程之间处理共享数据的方式

    题目要求: 有4个线程,其中两个线程每次对x加1,另外两个每次对x减1,如何实现? 分析: x就是这4个线程要处理的共享数据,不同种线程有不同的处理方式,但操作的数据是共同的,联想到"窗口买 ...

最新文章

  1. 获取access中表的相关信息
  2. SAP RETAIL初阶MM41创建商品主数据BASIC DATA里的Valuation Class
  3. 中芯国际再曝内讧,联席 CEO 梁孟松愤然辞职
  4. volatile 的内存语义
  5. Strong Consistency, 强一致性技术概述
  6. python操作mongodb语法_python 操作MongoDB
  7. 互联网职场就像一场《鱿鱼游戏》
  8. java aws s3_java操作AWS S3一些坑记录
  9. idea报错Module Project1 must not contain source root ...\Project1\src. The root already belongs to .
  10. 什么是容器服务_【小牛云计算课堂】什么是容器镜像服务
  11. [转]RamDisk导致远程桌面客户端无法启动问题
  12. VPX加固机箱学习资料第289篇:基于3U VPX的 5槽加固机箱
  13. 直觉模糊集的基本要素
  14. 互联网大佬生存法则:如何防守周鸿祎?
  15. QQ发送网址链接 安全性未知
  16. train_transformer.py 异常:Assertion `srcIndex < srcSelectDimSize` failed.
  17. arduino超声波测距接线图详细_Arduino Uno + HY-SRF05 超声波测距模块详细讲解演示实验...
  18. Linux文件名包含小括号处理
  19. 录屏转gif的好用小工具ScreenToGif,免费又好用!
  20. CATTI 三级笔译考试准备

热门文章

  1. 亚马逊个人创业这条路行的通吗?
  2. 嵌入式开发必须学习qt吗?
  3. SQL 基础(五)数据查询实战演练一
  4. 【机器学习系列】聊聊决策树
  5. java录入会员信息_Java编程语言基础 第三章 实现会员信息录入功能
  6. 什么是RS-485?
  7. 计算机sql查询同行并集,SQL查询交集、并集、差集
  8. ElasticSearch索引生命周期管理(ILM)
  9. Java实现满天星动案例
  10. 50欧姆线设计 高频pcb_pcb 50欧姆阻抗匹配设计技巧