线程执行的代码相同

   如果每个线程执行的代码相同,可以使用同一个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 多个线程之间共享数据的更多相关文章

  1. JAVA多线程提高四:多个线程之间共享数据的方式

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

  2. JAVA多线程学习八-多个线程之间共享数据的方式

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

  3. JAVA 并发编程-多个线程之间共享数据

    原文地址:http://blog.csdn.net/hejingyuan6/article/details/47053409# 多线程共享数据的方式: 1,如果每个线程执行的代码相同,可以使用同一个R ...

  4. JAVA 并发编程-多个线程之间共享数据(六)

    多线程共享数据的方式: 1.假设每一个线程运行的代码同样.能够使用同一个Runnable对象,这个Runnable对象中有那个共享数据,比如,卖票系统就能够这么做. 2,假设每一个线程运行的代码不同. ...

  5. 【转】JAVA 并发编程-多个线程之间共享数据

    原文地址:http://blog.csdn.net/hejingyuan6/article/details/47053409# 多线程共享数据的方式: 1,如果每个线程执行的代码相同,可以使用同一个R ...

  6. day33 线程的创建 验证线程之间共享数据 守护线程 线程进程效率对比 锁 死锁 递归锁

    今日内容: 1.线程理论 2.锁: 牺牲了效率,保证了数据的安全(重点) 3.守护线程 4.GIL锁:(重点) 5.计算密集型和IO密集型 6.信号量,事件(了解) 7.补充. 子进程中不能input ...

  7. Android多线程研究(5)——线程之间共享数据

    一.如果是每个线程都执行相同的代码,则可以使用同一个Runnable来实现共享 public class MultiThreadShareData { public static void main( ...

  8. Java并发基础09. 多个线程间共享数据问题

    先看一个多线程间共享数据的问题: 设计四个线程,其中两个线程每次对data增加1,另外两个线程每次对data减少1. 从问题来看,很明显涉及到了线程间通数据的共享,四个线程共享一个 data,共同操作 ...

  9. Disruptor 线程间共享数据无需竞争

    队列的作用是缓冲 缓冲到 队列的空间里.. 线程间共享数据无需竞争 原文 地址  作者  Trisha   译者:李同杰 LMAX Disruptor 是一个开源的并发框架,并获得2011 Duke’ ...

  10. 多线程(四) 实现线程范围内模块之间共享数据及线程间数据独立(Map集合)

    多个线程访问共享对象和数据的方式 1.如果每个线程执行的代码相同,可以使用同一个Runnable对象,这个Runnable对象中有那个共享数据,例如,买票系统就可以这么做. 2.如果每个线程执行的代码 ...

随机推荐

  1. linux mongodb安装

    更新依赖包 安装前我们需要安装各个 Linux 平台依赖包. Red Hat/CentOS: sudo yum install libcurl openssl Ubuntu 18.04 LTS (&q ...

  2. 搭建自己的OCR服务,第三步:PPOCRLabel标注工具安装

    一.安装说明 安装好了PaddleOCR后,还需要安装PPOCRLabel这个标注工具,想要自己训练模型的话,有个标注工具会起很大作用. 尤其是PPOCRLabel就是跟PaddleOCR配套的标注工 ...

  3. CSRF的理解及Flask和Django的解决方案

    CSRF 攻击的原理 1. 用户正常登录 网站A 2. 网站A 向用户浏览器写入cookies(包含登录信息) 3. 用户在没有登出的情况下,访问了网站B(攻击网站) 4. 网站B 伪造了一个 网站A ...

  4. 业余无线电之配置Orbitron My DDE 自动推送多普勒频率至SDRSharp程序中

    配置Orbitron My DDE 推送多普勒频率至SDR (By:BI8EJM) Start Edit Time 2021/8/16 23:03 要实现的功能:通过本次设置,让Orbitron程序自 ...

  5. C++基础学习--随记

    博客地址:https://www.cnblogs.com/zylyehuo/ 参考"C++基础与深度解析" 一.预备知识 // c++常用工具 /usr/bin/time //查看 ...

  6. Typora中插入分页符

    博客地址:https://www.cnblogs.com/zylyehuo/ <div style="page-break-after:always"></div ...

  7. 修改 Proxmox VE 6.0 LVM Thin 为存储分区

    PVE 安装后默认将 60G 的 SSD 分为了 14G 和 26G 的两个分区,其中 25G 为 LVM Thin,用于ISO镜像存储的分区为 14G,明显不够用,传一个 WInServer2016 ...

  8. 【Java】修饰符

    修饰符(Modifier):是用于限定类型以及类型成员的声明的一种符号. 其用来定义类.方法或者变量,通常放在语句的最前端. 例子: public class Person { default Str ...

  9. Cannot find one or more components.

    场景重现 有那么一天重启了下电脑, 打开 Microsoft SQL Server Management Studio 2016, 没有出现腻歪的用户界面, 反而出现如下异常: 错误原因 谁造呢? 有 ...

  10. study Python3【2】导入模块

    import 与 from...import 在 python 用 import 或者 from...import 来导入相应的模块. 将整个模块(somemodule)导入,格式为: import ...