线程执行的代码相同

   如果每个线程执行的代码相同,可以使用同一个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. ITIL4 变更管理核心流程笔记

  2. sudo: unable to resolve host xxxx: Name or service not known

    前言 在 Linux 环境中,我使用 sudo 执行命令,发生报错:sudo: unable to resolve host xxxx: Name or service not known 解决 这个 ...

  3. golang gin框架使用swagger生成接口文档

    前言 一份清晰明了的接口文档能够极大地提高前后端双方的沟通效率和开发效率. 本文将介绍如何使用swagger生成接口文档. swagger介绍 Swagger本质上是一种用于描述使用JSON表示的RE ...

  4. 开源组件DockerFIle老是Build失败,如何解决

    推荐把外网地址替换为国内高速镜像 # 替换源地址 http://dl-cdn.alpinelinux.org/alpine === https://mirrors.aliyun.com/alpine ...

  5. 文件批量重命名神器:Bulk Rename Utility

    内容摘要: 你还在手动给文件重命名吗?介绍一款免费而强大的批量重命名神器:Bulk Rename Utility,它将满足你对批量改名的所有期待.让它将你从痛苦的重命名工作中解放吧! 软件获取地址 云 ...

  6. Delphi 禁止重复运行程序的方法

    第一种方法,使用"过程调用" procedure Del; // 自定义过程 var Mutex: THandle; begin Mutex := CreateMutex(nil, ...

  7. 什么是RESTful 或 GraphQL?

    RESTful 与 GraphQL 深度解析 在前端的开发过程中,相信 everyone 对 Get.POST 等请求方式都很熟悉,那么这些请求是归于哪种架构或者设计风格可能又不是很熟.现在在这简单的 ...

  8. 【手机】三星手机刷机解决SecSetupWizard已停止

    三星手机恢复出厂设置之后,出现SecSetupWizard已停止的解决方案 零.问题 我手上有一部同学给的三星 GT-S6812I,这几天搞了张新卡,多余出的卡就放到这个手机上玩去了.因为是获取了ro ...

  9. 阿里云平台OSS对象存储

    OSS即"OpenStorageService",概念上没啥新意,就是本地存储搬到阿里云平台上了,单个存储对象大小可以达到5G,看了下阿里的OSS教程java版本, 使用原生js和 ...

  10. python爬虫爬取B站视频字幕,简单的数据处理(pandas将字幕写入到CSV文件中)

    上文,我们爬取到B站视频的字幕:https://www.cnblogs.com/becks/p/14540355.html 这篇,讲讲怎么把爬到的字幕写到CSV文件中,以便用于后面的分析 本文主要用到 ...