JAVA 并发编程-多个线程之间共享数据(六)
多线程共享数据的方式:
1。假设每一个线程运行的代码同样。能够使用同一个Runnable对象,这个Runnable对象中有那个共享数据,比如,卖票系统就能够这么做。
2,假设每一个线程运行的代码不同。这时候须要用不同的Runnable对象,比如,设计4个线程。
当中两个线程每次对j添加1。另外两个线程对j每次减1。银行存取款
有两种方法来解决此类问题:
将共享数据封装成另外一个对象,然后将这个对象逐一传递给各个Runnable对象。每一个线程对共享数据的操作方法也分配到那个对象身上完毕,这样easy实现针对数据进行各个操作的相互排斥和通信
将Runnable对象作为一个类的内部类,共享数据作为这个类的成员变量,每一个线程对共享数据的操作方法也封装在外部类,以便实现对数据的各个操作的同步和相互排斥。作为内部类的各个Runnable对象调用外部类的这些方法。
以下逐一介绍
每一个线程运行的代码同样,能够使用同一个Runnable对象
卖票系统demo:
package com.tgb.hjy;
/**
* 多线程共享数据-卖票系统
* @author hejingyuan
*
*/
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.tgb.hjy;
public class TestThread {
/**
* @param args
*/
public static void main(String[] args) {
final MyData data = new MyData();
for(int i=0;i<2;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.tgb.hjy;
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 并发编程-多个线程之间共享数据
原文地址:http://blog.csdn.net/hejingyuan6/article/details/47053409# 多线程共享数据的方式: 1,如果每个线程执行的代码相同,可以使用同一个R ...
- Java并发编程--6.Exchanger线程间交换数据
在两个线程之间定义同步点,当两个线程都到达同步点时,他们交换数据结构,因此第一个线程的数据结构进入到第二个线程中,第二个线程的数据结构进入到第一个线程中 在生产者-消费者情境模式中它包含了一个数缓冲区 ...
- Java并发编程系列-(2) 线程的并发工具类
2.线程的并发工具类 2.1 Fork-Join JDK 7中引入了fork-join框架,专门来解决计算密集型的任务.可以将一个大任务,拆分成若干个小任务,如下图所示: Fork-Join框架利用了 ...
- 【Java并发编程一】线程安全和共享对象
一.什么是线程安全 当多个线程访问一个类时,如果不用考虑这些线程在运行时环境下的调度和交替执行,并且不需要额外的同步及在调用代码代码不必作其他的协调,这个类的行为仍然是正确的,那么称这个类是线程安全的 ...
- Java并发编程实战 之 对象的共享
上一篇介绍了如何通过同步多个线程避免同一时刻访问相同数据,本篇介绍如何共享和发布对象,使它们被安全地由多个进程访问. 1.可见性 通常,我们无法保证执行读操作的线程能看到其他线程写入的值,因为每个线程 ...
- 【java并发编程实战】-----线程基本概念
学习Java并发已经有一个多月了,感觉有些东西学习一会儿了就会忘记,做了一些笔记但是不系统,对于Java并发这么大的"系统",需要自己好好总结.整理才能征服它.希望同仁们一起来学习 ...
- Java并发编程扩展(线程通信、线程池)
之前我说过,实现多线程的方式有4种,但是之前的文章中,我只介绍了两种,那么下面这两种,可以了解了解,不懂没关系. 之前的文章-->Java并发编程之多线程 使用ExecutorService.C ...
- Java并发编程:进程和线程的由来(转)
Java多线程基础:进程和线程之由来 在前面,已经介绍了Java的基础知识,现在我们来讨论一点稍微难一点的问题:Java并发编程.当然,Java并发编程涉及到很多方面的内容,不是一朝一夕就能够融会贯通 ...
随机推荐
- Vertica7 Native Connection Load Balance
原文链接:Vertica7 Native Connection Load Balance 在Vertica7曾经的版本号中,Vertica是通过Linux的Virtual IP来实现连接的负载均衡的, ...
- 【bat】通过for循环复制一张图片100次
代码如下: @echo off set "F=1" cd C:\Users\Thinkpad\Desktop\img for /L %%F IN (1,1,100) DO COPY ...
- java线程--volatile实现可见性
volatile关键字: 1)能够保证volatile变量的可见性 2)不能保证volatile变量复杂操作的原子性. volatile如何实现内存可见性: 深入来说:通过加入内存屏障和禁止重排序优化 ...
- 转:RHEL6.3 安装GCC 记录
本文参考:http://blog.163.com/phys_atom/blog/static/1676445532012229814992/ 如果直接使用GUN GCC官方的源码来安装是不成功的,因为 ...
- Android 打造完美的侧滑菜单/侧滑View控件
概述 Android 打造完美的侧滑菜单/侧滑View控件,完全自定义实现,支持左右两个方向弹出,代码高度简洁流畅,兼容性高,控件实用方便. 详细 代码下载:http://www.demodashi. ...
- cygwin下安装scws
安装gcc和make命令 1.找到cygwin的etc目录中有一个名为passwd的文件. 2.用UE或记事本打开passwd这个文件,找到以下部分,把其中的windows用户名admin换成ro ...
- mosquitto 启动命令
启动命令 mosquitto [-c config file] [ -d | --daemon ] [-p port number] [-v] -c 后面跟的是启动mosquitto可以调整的参数,比 ...
- zeroclipboard解决跨域问题
ZeroClipboard.setDefaults({ moviePath: "//d2glos6gx2bw40.cloudfront.net/C8QpR9/images/flash/Zer ...
- 在CentOS上安装部署MooseFS分布式文件系统
参考资料: http://www.moosefs.org/tl_files/manpageszip/moosefs-step-by-step-tutorial-cn-v.1.1.pdf 环境介绍:OS ...
- action(二)
RemoveSelf :消失 CCFiniteTimeAction* action = CCSequence::create( CCMoveBy::create( , ccp(,)), CCRotat ...