Java 多个线程之间共享数据
线程执行的代码相同
如果每个线程执行的代码相同,可以使用同一个Runnable对象,在这个Runnable对象中定义共享数据即可,例如,卖票系统就可以这么做。
public class SellTicket {
//卖票系统,多个窗口的处理逻辑是相同的
public static void main(String[] args) {
Ticket t = new Ticket();
new Thread(t).start();
new Thread(t).start();
}}
/**
* 将属性和处理逻辑封装在同一个类中
*
* @author Wiener
*/
class Ticket implements Runnable {
// 资源初始值
private int ticket = 10;
public synchronized void run() {
while (ticket > 0) {
ticket--;
System.out.println("当前票数为:" + ticket);
}
}}
每个线程执行的代码不同
如果每个线程执行的代码不同,这时候需要用不同的Runnable对象。例如,银行存取款系统中设计2个线程,一个线程对j增加1,另外一个线程对j减1。
将共享数据抽象到一个类中,并将对这个数据的操作作为这个类的方法,这么设计可以轻而易举地做到同步,只要在方法上加synchronized关键字即可。
package com.hoss.ext.authentication;
/**
* 两个线程执行的方法不一样
*
* @author Wiener
* @date 2021/4/25
*/
public class MultiThreadShareData {
// 库存10
private int j = 10;
public static void main(String[] args) {
MultiThreadShareData multiThreadShareData = new MultiThreadShareData();
for (int i = 0; i < 2; i++) {
//增加
new Thread(multiThreadShareData.new ShareData1()).start();
//减少
new Thread(multiThreadShareData.new ShareData2()).start();
}
}
//自增
private synchronized void Inc() {
j++;
System.out.println(Thread.currentThread().getName() + " inc " + j);
}
//自减
private synchronized void Dec() {
j--;
System.out.println(Thread.currentThread().getName() + " dec " + j);
}
class ShareData1 implements Runnable {
@Override
public void run() {
for (int i = 0; i < 5; i++) {
Inc();
}
}
}
class ShareData2 implements Runnable {
@Override
public void run() {
for (int i = 0; i < 5; i++) {
Dec();
}
}
}
}
执行结果如下:
Thread-1 dec 9
Thread-1 dec 8
Thread-1 dec 7
Thread-1 dec 6
Thread-1 dec 5
Thread-3 dec 4
Thread-3 dec 3
Thread-3 dec 2
Thread-3 dec 1
Thread-3 dec 0
Thread-2 inc 1
Thread-2 inc 2
Thread-2 inc 3
Thread-2 inc 4
Thread-2 inc 5
Thread-0 inc 6
Thread-0 inc 7
Thread-0 inc 8
Thread-0 inc 9
Thread-0 inc 10
关键还是思想:将共享数据和业务处理逻辑封装在一个类中,业务逻辑线程对象(即加1的线程和减1的线程操作)在执行时,直接调用该类中的处理逻辑。这样做,更符合面向对象,更易于维护。
总结一下,对于多线程间共享变量的操作,需要实现互斥,使得对该共享变量的操作实现原子性。
Reference
Java 多个线程之间共享数据的更多相关文章
- JAVA多线程提高四:多个线程之间共享数据的方式
多个线程访问共享对象和数据的方式 如果每个线程执行的代码相同,可以使用同一个Runnable对象,这个Runnable对象中有那个共享数据,例如,买票系统就可以这么做. 如果每个线程执行的代码不同,这 ...
- JAVA多线程学习八-多个线程之间共享数据的方式
多个线程访问共享对象和数据的方式 如果每个线程执行的代码相同,可以使用同一个Runnable对象,这个Runnable对象中有那个共享数据,例如,买票系统就可以这么做. 如果每个线程执行的代码不同,这 ...
- JAVA 并发编程-多个线程之间共享数据
原文地址:http://blog.csdn.net/hejingyuan6/article/details/47053409# 多线程共享数据的方式: 1,如果每个线程执行的代码相同,可以使用同一个R ...
- JAVA 并发编程-多个线程之间共享数据(六)
多线程共享数据的方式: 1.假设每一个线程运行的代码同样.能够使用同一个Runnable对象,这个Runnable对象中有那个共享数据,比如,卖票系统就能够这么做. 2,假设每一个线程运行的代码不同. ...
- 【转】JAVA 并发编程-多个线程之间共享数据
原文地址:http://blog.csdn.net/hejingyuan6/article/details/47053409# 多线程共享数据的方式: 1,如果每个线程执行的代码相同,可以使用同一个R ...
- day33 线程的创建 验证线程之间共享数据 守护线程 线程进程效率对比 锁 死锁 递归锁
今日内容: 1.线程理论 2.锁: 牺牲了效率,保证了数据的安全(重点) 3.守护线程 4.GIL锁:(重点) 5.计算密集型和IO密集型 6.信号量,事件(了解) 7.补充. 子进程中不能input ...
- Android多线程研究(5)——线程之间共享数据
一.如果是每个线程都执行相同的代码,则可以使用同一个Runnable来实现共享 public class MultiThreadShareData { public static void main( ...
- Java并发基础09. 多个线程间共享数据问题
先看一个多线程间共享数据的问题: 设计四个线程,其中两个线程每次对data增加1,另外两个线程每次对data减少1. 从问题来看,很明显涉及到了线程间通数据的共享,四个线程共享一个 data,共同操作 ...
- Disruptor 线程间共享数据无需竞争
队列的作用是缓冲 缓冲到 队列的空间里.. 线程间共享数据无需竞争 原文 地址 作者 Trisha 译者:李同杰 LMAX Disruptor 是一个开源的并发框架,并获得2011 Duke’ ...
- 多线程(四) 实现线程范围内模块之间共享数据及线程间数据独立(Map集合)
多个线程访问共享对象和数据的方式 1.如果每个线程执行的代码相同,可以使用同一个Runnable对象,这个Runnable对象中有那个共享数据,例如,买票系统就可以这么做. 2.如果每个线程执行的代码 ...
随机推荐
- linux mongodb安装
更新依赖包 安装前我们需要安装各个 Linux 平台依赖包. Red Hat/CentOS: sudo yum install libcurl openssl Ubuntu 18.04 LTS (&q ...
- 搭建自己的OCR服务,第三步:PPOCRLabel标注工具安装
一.安装说明 安装好了PaddleOCR后,还需要安装PPOCRLabel这个标注工具,想要自己训练模型的话,有个标注工具会起很大作用. 尤其是PPOCRLabel就是跟PaddleOCR配套的标注工 ...
- CSRF的理解及Flask和Django的解决方案
CSRF 攻击的原理 1. 用户正常登录 网站A 2. 网站A 向用户浏览器写入cookies(包含登录信息) 3. 用户在没有登出的情况下,访问了网站B(攻击网站) 4. 网站B 伪造了一个 网站A ...
- 业余无线电之配置Orbitron My DDE 自动推送多普勒频率至SDRSharp程序中
配置Orbitron My DDE 推送多普勒频率至SDR (By:BI8EJM) Start Edit Time 2021/8/16 23:03 要实现的功能:通过本次设置,让Orbitron程序自 ...
- C++基础学习--随记
博客地址:https://www.cnblogs.com/zylyehuo/ 参考"C++基础与深度解析" 一.预备知识 // c++常用工具 /usr/bin/time //查看 ...
- Typora中插入分页符
博客地址:https://www.cnblogs.com/zylyehuo/ <div style="page-break-after:always"></div ...
- 修改 Proxmox VE 6.0 LVM Thin 为存储分区
PVE 安装后默认将 60G 的 SSD 分为了 14G 和 26G 的两个分区,其中 25G 为 LVM Thin,用于ISO镜像存储的分区为 14G,明显不够用,传一个 WInServer2016 ...
- 【Java】修饰符
修饰符(Modifier):是用于限定类型以及类型成员的声明的一种符号. 其用来定义类.方法或者变量,通常放在语句的最前端. 例子: public class Person { default Str ...
- Cannot find one or more components.
场景重现 有那么一天重启了下电脑, 打开 Microsoft SQL Server Management Studio 2016, 没有出现腻歪的用户界面, 反而出现如下异常: 错误原因 谁造呢? 有 ...
- study Python3【2】导入模块
import 与 from...import 在 python 用 import 或者 from...import 来导入相应的模块. 将整个模块(somemodule)导入,格式为: import ...