多线程共享数据

news/2024/11/30 1:47:44/

在Java传统线程机制中的共享数据方式,大致可以简单分两种情况: 

➢  多个线行为共同作一个。也就是每个线程执行的代码相同,可以使用同一个Runnable对

象,这个Runnable对象中有那个共享数据,例如,卖票系统就可以这么做。 

➢  多个线程行为不一致共同一个数据。也就是每个线程执行的代码不同,这时候需要用不同的

Runnable对象。例如,银行存取款。 

下面我们通过两个示例代码来分别说明这两种方式。 

1.  多个线作一 

如果每个线程执行的代码相同,可以使用同一个Runnable对象,这个Runnable对象中有那个共享数据,例如,

买票系统就可以这么做。 

/**

*共享数据类 

**/

class ShareData{

private int num = 10 ; 

public  synchronized void inc() { 

num++;
System.out.println(Thread.currentThread().getName()+": invoke  inc method num =" + num); try {

Thread.sleep(1000); 

} catch (InterruptedException e) { 

e.printStackTrace(); 

}

}

}

/**

*多线程类 

**/

class RunnableCusToInc implements Runnable{ 

private ShareData  shareData; 

public RunnableCusToInc(ShareData data) { 

this.shareData = data; 

}

@Override

public void run() {

for (int i = 0; i < 5; i++) { 

shareData.inc(); 

}

}

}

/**

*测试方法 

**/ 

public static void main(String[] args) { 

ShareData    shareData = new ShareData();

for (int i = 0; i < 4; i++) { 

new Thread(new    RunnableCusToInc(shareData),"Thread "+ i).start();

}

}

2.  多个线操作数据 

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

象之间的数据共享: 

1)  将共享数据封装在另外一个对象中,然后将这个对象逐一传递给各个 Runnable 对象。每个线程对共享

数据的操作方法也分配到那个对象身上去完成,这样容易实现针对该数据进行的各个操作的互斥和通信。 

public static void main(String[] args) {

ShareData    shareData = new ShareData();

for (int i = 0; i < 4; i++) { 

if(i%2 == 0){

new Thread(new    RunnableCusToInc(shareData),"Thread "+ i).start();

}else{

new Thread(new    RunnableCusToDec(shareData),"Thread "+ i).start(); 

}

}

}

//封装共享数据类 

class RunnableCusToInc implements Runnable{ 

//封装共享数据 

private ShareData    shareData; 

public RunnableCusToInc(ShareData data) { 

this.shareData = data; 

}

@Override

public void run() { 

for (int i = 0; i < 5; i++) {

shareData.inc(); 

}

}

}

//封装共享数据类 

class RunnableCusToDec implements Runnable{ 

//封装共享数据 

private ShareData    shareData; 

public RunnableCusToDec(ShareData data) { 

this.shareData = data; 

}

@Override

public void run() { 

for (int i = 0; i < 5; i++) {

shareData.dec(); 

}

}

}

/**

*共享数据类 

**/

class ShareData{

private int num = 10 ; 

public  synchronized void inc() { 

num++;
System.out.println(Thread.currentThread().getName()+": invoke  inc method num =" + num); 

try {

Thread.sleep(1000); 

} catch (InterruptedException e) { 

e.printStackTrace(); 

}

}

2)  将这些 Runnable 对象作为某一个类中的内部类,共享数据作为这个外部类中的成员变量,每个线程对

共享数据的操作方法也分配给外部类,以便实现对共享数据进行的各个操作的互斥和通信,作为内部类的各个

Runnable对象调用外部类的这些方法。 

public static void main(String[] args) { 

//公共数据 

final ShareData  shareData = new ShareData(); 

for (int i = 0; i < 4; i++) { 

if(i%2 == 0){

new Thread(new Runnable() { 

@Override

public void run() { 

for (int i = 0; i < 5; i++) { 

shareData.inc(); 

}

}

},"Thread "+ i).start(); 

}else{

new Thread(new Runnable() { 

@Override

public void run() { 

for (int i = 0; i < 5; i++) { 

shareData.dec(); 

}

}

},"Thread "+ i).start(); 

}

}

}

class ShareData{

private int num = 10 ; 

public  synchronized void inc() {

num++;
System.out.println(Thread.currentThread().getName()+": invoke  inc method num =" + num); try {

Thread.sleep(1000); 

} catch (InterruptedException e) { 

e.printStackTrace(); 

}

}

public synchronized void dec() { 

num--;
System.err.println(Thread.currentThread().getName()+": invoke  dec  method num =" + num); try {

Thread.sleep(1000); 

} catch (InterruptedException e) { 

e.printStackTrace(); 

}

}

}

补充两种式的将共数据装在外一个象中,每个线对共享据的作方法也分配到那个对身上完成象作为个外类中员变量方法的局部变线程Runnable对象作为外类中成员内部类或局内部类。 

总之步互的几代码最是分放在独立的法中,这些方再放在一个比较容易实现们之的同步互斥和通信。 


http://www.ppmy.cn/news/104832.html

相关文章

Leetcode11 盛最多水的容器

Leetcode11 盛最多水的容器 来源&#xff1a;力扣&#xff08;LeetCode&#xff09; 链接&#xff1a;https://leetcode.cn/problems/container-with-most-water/description 博主Github&#xff1a;https://github.com/GDUT-Rp/LeetCode 题目&#xff1a; 给定一个长度为 n…

[论文阅读73]Prefix-Tuning:Optimizing Continuous Prompts for Generation

1. 基本信息 题目论文作者与单位来源年份Prefix-Tuning&#xff1a;Optimizing Continuous Prompts for GenerationXiang Lisa Li等 Stanford UniversityAnnual Meeting of the Association for Computational Linguistics2021 Citations 1009, References 论文链接&#xf…

中国人工智能学会主办!真实AIGC业务数据驱动,欢迎全球开发者参加

近期&#xff0c;由百度商业联合中国人工智能学会举办、NVIDIA提供战略支持&#xff0c;百度飞桨承办的“百度商业AI技术创新大赛”正式启动&#xff0c;启动会现场&#xff0c;中国工程院院士、中国人工智能学会理事长、清华大学信息科学技术学院院长戴琼海院士通过视频方式对…

Springboot整合Swagger2(3.0.0版本)

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…

数据库读写锁

0、概要 1、谈⼀谈MySQL的读写锁 2、隔离级别与锁的关系 3、按照锁的粒度分数据库锁有哪些&#xff1f;锁机制与InnoDB锁算法 4、从锁的类别上分MySQL都有哪些锁呢&#xff1f;像上⾯那样⼦进⾏锁定岂不是有点阻碍并发效率了 5、MySQL中InnoDB引擎的⾏锁是怎么实现的&#xff1…

代码随想录算法训练营第三十九天 | 力扣 62.不同路径, 63. 不同路径 II

62.不同路径 题目 62. 不同路径 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Finish” &#xff09;。 问总共有多…

Effective STL_读书笔记

Effective STL 1. 容器条例01&#xff1a;慎重选择容器类型条例02&#xff1a;不要试图编写独立于容器类型的代码条例03&#xff1a;确保容器中对象的拷贝正确而高效条例04&#xff1a;调用empty而不是检查size()是否为空条例05&#xff1a;区间成员函数优先于与之对应的单元素…

python:绘制GAM非线性回归

作者&#xff1a;CSDN _养乐多_ 本文将介绍使用python语言绘制广义线性模型&#xff08;Generalized Additive Model&#xff0c;GAM&#xff09;非线性回归散点图和拟合曲线。并记录了计算RMSE、ubRMSE、R2、Bias的代码。 文章目录 一、GAM非线性回归详解二、代码三、计算RM…