【转】JAVA 并发编程-多个线程之间共享数据
原文地址: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 {
/**
* @param args
*/
public static void main(String[] args) {
final MyData data = new MyData();
for (int i = 0; i < 10; i++) {
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 = 0;
public synchronized void add() {
j++;
System.out.println("线程" + Thread.currentThread().getName() + "j为:" + j);
}
public synchronized void dec() {
j--;
System.out.println("线程" + Thread.currentThread().getName() + "j为:" + j);
}
}

银行存取款实例:
package com.xujishou;
public class Acount {
private int money;
public Acount(int money) {
this.money = money;
}
public synchronized void getMoney(int money) {
// 注意这个地方必须用while循环,因为即便再存入钱也有可能比取的要少
while (this.money < money) {
System.out.println("取款:" + money + " 余额:" + this.money
+ " 余额不足,正在等待存款......");
try {
wait();
} catch (Exception e) {
}
}
this.money = this.money - money;
System.out.println("取出:" + money + " 还剩余:" + this.money);
}
public synchronized void setMoney(int money) {
try {
Thread.sleep(10);
} catch (Exception e) {
}
this.money = this.money + money;
System.out.println("新存入:" + money + " 共计:" + this.money);
notify();
}
public static void main(String args[]) {
Acount Acount = new Acount(0);
Bank b = new Bank(Acount);
Consumer c = new Consumer(Acount);
new Thread(b).start();
new Thread(c).start();
}
}
// 存款类
class Bank implements Runnable {
Acount Acount;
public Bank(Acount Acount) {
this.Acount = Acount;
}
public void run() {
while (true) {
int temp = (int) (Math.random() * 1000);
Acount.setMoney(temp);
}
}
}
// 取款类
class Consumer implements Runnable {
Acount Acount;
public Consumer(Acount Acount) {
this.Acount = Acount;
}
public void run() {
while (true) {
int temp = (int) (Math.random() * 1000);
Acount.getMoney(temp);
}
}
}

总结:
其实多线程间的共享数据最主要的还是互斥,多个线程共享一个变量,针对变量的操作实现原子性即可。
【转】JAVA 并发编程-多个线程之间共享数据的更多相关文章
- JAVA 并发编程-多个线程之间共享数据
原文地址:http://blog.csdn.net/hejingyuan6/article/details/47053409# 多线程共享数据的方式: 1,如果每个线程执行的代码相同,可以使用同一个R ...
- JAVA 并发编程-多个线程之间共享数据(六)
多线程共享数据的方式: 1.假设每一个线程运行的代码同样.能够使用同一个Runnable对象,这个Runnable对象中有那个共享数据,比如,卖票系统就能够这么做. 2,假设每一个线程运行的代码不同. ...
- Java并发编程--6.Exchanger线程间交换数据
在两个线程之间定义同步点,当两个线程都到达同步点时,他们交换数据结构,因此第一个线程的数据结构进入到第二个线程中,第二个线程的数据结构进入到第一个线程中 在生产者-消费者情境模式中它包含了一个数缓冲区 ...
- Java并发编程系列-(2) 线程的并发工具类
2.线程的并发工具类 2.1 Fork-Join JDK 7中引入了fork-join框架,专门来解决计算密集型的任务.可以将一个大任务,拆分成若干个小任务,如下图所示: Fork-Join框架利用了 ...
- 【Java并发编程一】线程安全和共享对象
一.什么是线程安全 当多个线程访问一个类时,如果不用考虑这些线程在运行时环境下的调度和交替执行,并且不需要额外的同步及在调用代码代码不必作其他的协调,这个类的行为仍然是正确的,那么称这个类是线程安全的 ...
- 【java并发编程实战】-----线程基本概念
学习Java并发已经有一个多月了,感觉有些东西学习一会儿了就会忘记,做了一些笔记但是不系统,对于Java并发这么大的"系统",需要自己好好总结.整理才能征服它.希望同仁们一起来学习 ...
- Java并发编程:进程和线程的由来(转)
Java多线程基础:进程和线程之由来 在前面,已经介绍了Java的基础知识,现在我们来讨论一点稍微难一点的问题:Java并发编程.当然,Java并发编程涉及到很多方面的内容,不是一朝一夕就能够融会贯通 ...
- 【Java并发编程六】线程池
一.概述 在执行并发任务时,我们可以把任务传递给一个线程池,来替代为每个并发执行的任务都启动一个新的线程,只要池里有空闲的线程,任务就会分配一个线程执行.在线程池的内部,任务被插入一个阻塞队列(Blo ...
- Java并发编程扩展(线程通信、线程池)
之前我说过,实现多线程的方式有4种,但是之前的文章中,我只介绍了两种,那么下面这两种,可以了解了解,不懂没关系. 之前的文章-->Java并发编程之多线程 使用ExecutorService.C ...
随机推荐
- 【学步者日记】UnityEditor扩展菜单以及ScriptableObject
完整版链接:http://note.youdao.com/noteshare?id=c54f35ca19371886e6a94302387bb6cd 下面是预览的部分,带图的版本请看上面链接. ...
- 第七章 Rolling update
7.1 实践 apiVersion: apps/v1beta1 kind: Deployment metadata: name: httpd spec: replicas: 3 template: m ...
- Java 中 wait, notify 和 notifyAll的正确使用 – 以生产者消费者模型为例
如何使用Wait 尽管关于wait和notify的概念很基础,它们也都是Object类的函数,但用它们来写代码却并不简单.如果你在面试中让应聘者来手写代码,用wait和notify解决生产者消费者问题 ...
- 如何用xMind打开.mmap文件
首先右键单击mmap格式文档,选择“属性” > “更改了打开方式” > 选择使用Xmind软件打开.然后双击mmap格式文档,就可以用Xmind打开了!
- 深入浅出 Java Concurrency (13): 锁机制 part 8 读写锁 (ReentrantReadWriteLock) (1)
从这一节开始介绍锁里面的最后一个工具:读写锁(ReadWriteLock). ReentrantLock 实现了标准的互斥操作,也就是一次只能有一个线程持有锁,也即所谓独占锁的概念.前面的章节中一 ...
- 用CSS制作小三角提示符号
今天在项目中遇到了如下图的切图要求. 对,重点就是那个小三角提示符号. html 结构如下 <div class="wrap"> <div class=" ...
- mysql update更新带子查询的实现方式
现在要做一下数据移植,需要更新相关的数据,需要在mysql中更新时不能将更新的表作为查询的表. 总结一下: 一:单表更新时 例如: update customer set category = 1 W ...
- Echart ---超详细介绍
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...
- 如何把MyEclipse中的web项目导入到Eclipse中运行
有时我们需要将MyEclipse中的项目导入到Eclipse中运行,如果不注意到一些细节,会造成无法运行的后果.下面就说说具体操作: 如何导入到Eclipse就不在重述了,导入后出现如下错误: 与上面 ...
- Scrum由来
历史故事 在越南战争期间(1955年-1975年),对于美国战机飞行员而言,要执行100次飞行任务,飞到敌国领空被击落的概率是50%. 1967年,萨瑟兰还是一个没有经验的年轻飞行员,当时却是做最危险 ...