热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

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

原文地址:http:blog.csdn.nethejingyuan6articledetails47053409#多线程共享数据的方式:1,

原文地址:http://blog.csdn.net/hejingyuan6/article/details/47053409#

多线程共享数据的方式:

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

2,如果每个线程执行的代码不同,这时候需要用不同的Runnable对象,例如,设计4个线程。其中两个线程每次对j增加1,另外两个线程对j每次减1,银行存取款

 

有两种方法来解决此类问题:

将共享数据封装成另外一个对象,然后将这个对象逐一传递给各个Runnable对象,每个线程对共享数据的操作方法也分配到那个对象身上完成,这样容易实现针对数据进行各个操作的互斥和通信

将Runnable对象作为一个类的内部类,共享数据作为这个类的成员变量,每个线程对共享数据的操作方法也封装在外部类,以便实现对数据的各个操作的同步和互斥,作为内部类的各个Runnable对象调用外部类的这些方法。

 

下面逐一介绍

 

每个线程执行的代码相同,可以使用同一个Runnable对象

卖票系统demo:

package com.xujishou;public class SellTicket {/*** @param args*/public static void main(String[] args) {Ticket t = new Ticket();new Thread(t).start();new Thread(t).start();}
}class Ticket implements Runnable {private int ticket = 10;public void run() {while (ticket > 0) {ticket--;System.out.println("当前票数为:" + ticket);}}
}

 

 执行

简单的多线程间数据共享,每个线程执行的代码不同,用不同的Runnable对象

设计4个线程。

其中两个线程每次对j增加1,另外两个线程对j每次减1

package com.xujishou;public class TestThread {/*** &#64;param args*/public static void main(String[] args) {final MyData data &#61; new MyData();for (int i &#61; 0; i <10; i&#43;&#43;) {new Thread(new Runnable() {public void run() {data.add();}}).start();new Thread(new Runnable() {public void run() {data.dec();}}).start();}}}class MyData {private int j &#61; 0;public synchronized void add() {j&#43;&#43;;System.out.println("线程" &#43; Thread.currentThread().getName() &#43; "j为&#xff1a;" &#43; j);}public synchronized void dec() {j--;System.out.println("线程" &#43; Thread.currentThread().getName() &#43; "j为&#xff1a;" &#43; j);}}

 

 

银行存取款实例&#xff1a;

package com.xujishou;public class Acount {private int money;public Acount(int money) {this.money &#61; money;}public synchronized void getMoney(int money) {// 注意这个地方必须用while循环&#xff0c;因为即便再存入钱也有可能比取的要少while (this.money }// 存款类
class Bank implements Runnable {Acount Acount;public Bank(Acount Acount) {this.Acount &#61; Acount;}public void run() {while (true) {int temp &#61; (int) (Math.random() * 1000);Acount.setMoney(temp);}}}// 取款类
class Consumer implements Runnable {Acount Acount;public Consumer(Acount Acount) {this.Acount &#61; Acount;}public void run() {while (true) {int temp &#61; (int) (Math.random() * 1000);Acount.getMoney(temp);}}
}

  

总结&#xff1a;

    其实多线程间的共享数据最主要的还是互斥&#xff0c;多个线程共享一个变量&#xff0c;针对变量的操作实现原子性即可。

  

  

 

转:https://www.cnblogs.com/xujishou/p/6640677.html



推荐阅读
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • 本文介绍了Java高并发程序设计中线程安全的概念与synchronized关键字的使用。通过一个计数器的例子,演示了多线程同时对变量进行累加操作时可能出现的问题。最终值会小于预期的原因是因为两个线程同时对变量进行写入时,其中一个线程的结果会覆盖另一个线程的结果。为了解决这个问题,可以使用synchronized关键字来保证线程安全。 ... [详细]
  • Java自带的观察者模式及实现方法详解
    本文介绍了Java自带的观察者模式,包括Observer和Observable对象的定义和使用方法。通过添加观察者和设置内部标志位,当被观察者中的事件发生变化时,通知观察者对象并执行相应的操作。实现观察者模式非常简单,只需继承Observable类和实现Observer接口即可。详情请参考Java官方api文档。 ... [详细]
  • Java太阳系小游戏分析和源码详解
    本文介绍了一个基于Java的太阳系小游戏的分析和源码详解。通过对面向对象的知识的学习和实践,作者实现了太阳系各行星绕太阳转的效果。文章详细介绍了游戏的设计思路和源码结构,包括工具类、常量、图片加载、面板等。通过这个小游戏的制作,读者可以巩固和应用所学的知识,如类的继承、方法的重载与重写、多态和封装等。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 本文介绍了一个Java猜拳小游戏的代码,通过使用Scanner类获取用户输入的拳的数字,并随机生成计算机的拳,然后判断胜负。该游戏可以选择剪刀、石头、布三种拳,通过比较两者的拳来决定胜负。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 关键词:Golang, Cookie, 跟踪位置, net/http/cookiejar, package main, golang.org/x/net/publicsuffix, io/ioutil, log, net/http, net/http/cookiejar ... [详细]
  • 多维数组的使用
    本文介绍了多维数组的概念和使用方法,以及二维数组的特点和操作方式。同时还介绍了如何获取数组的长度。 ... [详细]
  • Spring学习(4):Spring管理对象之间的关联关系
    本文是关于Spring学习的第四篇文章,讲述了Spring框架中管理对象之间的关联关系。文章介绍了MessageService类和MessagePrinter类的实现,并解释了它们之间的关联关系。通过学习本文,读者可以了解Spring框架中对象之间的关联关系的概念和实现方式。 ... [详细]
  • 数组的排序:数组本身有Arrays类中的sort()方法,这里写几种常见的排序方法。(1)冒泡排序法publicstaticvoidmain(String[]args ... [详细]
  • 面向对象之3:封装的总结及实现方法
    本文总结了面向对象中封装的概念和好处,以及在Java中如何实现封装。封装是将过程和数据用一个外壳隐藏起来,只能通过提供的接口进行访问。适当的封装可以提高程序的理解性和维护性,增强程序的安全性。在Java中,封装可以通过将属性私有化并使用权限修饰符来实现,同时可以通过方法来访问属性并加入限制条件。 ... [详细]
  • (三)多表代码生成的实现方法
    本文介绍了一种实现多表代码生成的方法,使用了java代码和org.jeecg框架中的相关类和接口。通过设置主表配置,可以生成父子表的数据模型。 ... [详细]
  • Android系统源码分析Zygote和SystemServer启动过程详解
    本文详细解析了Android系统源码中Zygote和SystemServer的启动过程。首先介绍了系统framework层启动的内容,帮助理解四大组件的启动和管理过程。接着介绍了AMS、PMS等系统服务的作用和调用方式。然后详细分析了Zygote的启动过程,解释了Zygote在Android启动过程中的决定作用。最后通过时序图展示了整个过程。 ... [详细]
  • 使用eclipse创建一个Java项目的步骤
    本文介绍了使用eclipse创建一个Java项目的步骤,包括启动eclipse、选择New Project命令、在对话框中输入项目名称等。同时还介绍了Java Settings对话框中的一些选项,以及如何修改Java程序的输出目录。 ... [详细]
author-avatar
php小盗
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有