JAVA多线程提高四:多个线程之间共享数据的方式
多个线程访问共享对象和数据的方式
如果每个线程执行的代码相同,可以使用同一个Runnable对象,这个Runnable对象中有那个共享数据,例如,买票系统就可以这么做。
如果每个线程执行的代码不同,这时候需要用不同的Runnable对象,有如下两种方式来实现这些Runnable对象之间的数据共享:
Ø将共享数据封装在另外一个对象中,然后将这个对象逐一传递给各个Runnable对象。每个线程对共享数据的操作方法也分配到那个对象身上去完成,这样容易实现针对该数据进行的各个操作的互斥和通信。
Ø将这些Runnable对象作为某一个类中的内部类,共享数据作为这个外部类中的成员变量,每个线程对共享数据的操作方法也分配给外部类,以便实现对共享数据进行的各个操作的互斥和通信,作为内部类的各个Runnable对象调用外部类的这些方法。
Ø上面两种方式的组合:将共享数据封装在另外一个对象中,每个线程对共享数据的操作方法也分配到那个对象身上去完成,对象作为这个外部类中的成员变量或方法中的局部变量,每个线程的Runnable对象作为外部类中的成员内部类或局部内部类。
Ø总之,要同步互斥的几段代码最好是分别放在几个独立的方法中,这些方法再放在同一个类中,这样比较容易实现它们之间的同步互斥和通信。
极端且简单的方式,即在任意一个类中定义一个static的变量,这将被所有线程共享。
需求:设计4个线程,其中两个线程每次对j增加1,另外两个线程对j减少1.
1.使用同一个runnable对象
如果每个线程执行的代码相同,那么可以使用同一个runnable对象,这个runnable有那个共享数据,例如,卖票系统就是这么做的.
...
public static void main(String[] args) {
ShareData1 shareData1 = new ShareData1();
new Thread(shareData1).start();
new Thread(shareData1).start();
} static class ShareData1 implements Runnable {
public int count = 100;
public void run() {
count--;
System.out.println("run:"+count);
}
} ...
2.使用不同的runnable对象
如果每个线程执行的代码不同,那么要使用不同的runnable对象,有如下两种方式可以实现runnable对象间的数据共享
1).实现两个runnable对象,将共享数据分别传递给两个不同线程.
....
public static void main(String[] args) {
final ShareData1 shareData1 = new ShareData1();
new Thread(new MyRunnable1(shareData1)).start();
new Thread(new MyRunnable1(shareData1)).start();
}
static class MyRunnable1 implements Runnable{
private ShareData1 shareData1;
public void run() {
}
public MyRunnable1(ShareData1 shareData1){
this.shareData1 = shareData1;
}
}
static class MyRunnable2 implements Runnable{
private ShareData1 shareData1;
public void run() {
}
public MyRunnable2(ShareData1 shareData1){
this.shareData1 = shareData1;
}
}
static class ShareData1 {
....
}
......
2).将这些Runnable对象作为一个内部类,将共享数据作为成员变量.
public class MultiThreadShareData {
private int j;
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 {
public void run() {
for(int i=0;i<5;i++){
Inc();
}
}
}
class ShareData2 implements Runnable {
public void run() {
for(int i=0;i<5;i++){
Dec();
}
}
}
}
效果:

注:
1.上面的代码,首先,是定义了一个全局的变量j,即共享数据;然后,实现Runnable对象,分别去做自增和自减的操作,然后将实现了的Runnable对象作为一个内部类塞给新建的线程;最后循环两遍,实现两个自减和两个自增线程.
2.这里要注意的是之所以将自增和自减提出来,是为了方便进行线程安全控制.
3.方法二和方法一的区别在于,方法一是主动将共享数据赋给Runnable对象,方法二则是将数据置为全局变量,然后进行操作.
参考资料:
《多线程》张孝祥视频
JAVA多线程提高四:多个线程之间共享数据的方式的更多相关文章
- JAVA多线程学习八-多个线程之间共享数据的方式
多个线程访问共享对象和数据的方式 如果每个线程执行的代码相同,可以使用同一个Runnable对象,这个Runnable对象中有那个共享数据,例如,买票系统就可以这么做. 如果每个线程执行的代码不同,这 ...
- Java多线程之~~~使用Exchanger在线程之间交换数据[这个结合多线程并行会有解决很多问题]生产者消费者模型
http://blog.csdn.net/a352193394/article/details/39503857 Java多线程之~~~使用Exchanger在线程之间交换数据[这个结合多线程并行会 ...
- Android多线程研究(5)——线程之间共享数据
一.如果是每个线程都执行相同的代码,则可以使用同一个Runnable来实现共享 public class MultiThreadShareData { public static void main( ...
- Java并发基础09. 多个线程间共享数据问题
先看一个多线程间共享数据的问题: 设计四个线程,其中两个线程每次对data增加1,另外两个线程每次对data减少1. 从问题来看,很明显涉及到了线程间通数据的共享,四个线程共享一个 data,共同操作 ...
- JAVA 并发编程-多个线程之间共享数据
原文地址:http://blog.csdn.net/hejingyuan6/article/details/47053409# 多线程共享数据的方式: 1,如果每个线程执行的代码相同,可以使用同一个R ...
- JAVA 并发编程-多个线程之间共享数据(六)
多线程共享数据的方式: 1.假设每一个线程运行的代码同样.能够使用同一个Runnable对象,这个Runnable对象中有那个共享数据,比如,卖票系统就能够这么做. 2,假设每一个线程运行的代码不同. ...
- 【转】JAVA 并发编程-多个线程之间共享数据
原文地址:http://blog.csdn.net/hejingyuan6/article/details/47053409# 多线程共享数据的方式: 1,如果每个线程执行的代码相同,可以使用同一个R ...
- 多个Activity之间共享数据的方式
现在要做一个项目,多个Activity之间要共享数据,所以要考虑共享数据的方式. 其实有如下5种方式: 1.基于消息的通信机制 Intent ---bundle ,extra 数据类型有限,比如遇到 ...
- day33 线程的创建 验证线程之间共享数据 守护线程 线程进程效率对比 锁 死锁 递归锁
今日内容: 1.线程理论 2.锁: 牺牲了效率,保证了数据的安全(重点) 3.守护线程 4.GIL锁:(重点) 5.计算密集型和IO密集型 6.信号量,事件(了解) 7.补充. 子进程中不能input ...
随机推荐
- HttpWebRequest下载文件,乱码问题解决方案
写在前面 今天之所以会总结HttpWebRequest下载文件,主要是因为在使用该类下载文件的时候,有些地方需要注意一下,在实际的项目中遇到过这种问题,觉得还是有必要总结一下的.在下载文件时,最常见的 ...
- lintcode-382-三角形计数
382-三角形计数 给定一个整数数组,在该数组中,寻找三个数,分别代表三角形三条边的长度,问,可以寻找到多少组这样的三个数来组成三角形? 样例 例如,给定数组 S = {3,4,6,7},返回 3 其 ...
- 【week10】psp
项目 内容 开始时间 结束时间 中断时间 净时间 2016/11/19(星期六) 写博客 吉林一日游规格说明书 10:30 15:10 20 260 2016/11/20(星期日) 看论文 磷酸化+三 ...
- css实现 显示一行文字,超出用...代替
overflow:hidden; white-space:nowrap; text-overflow:ellipsis;
- java 重写父类构造器
- (转)slf4j+logback将日志输出到控制台
因为博主不允许转载...这边做链接记录 http://blog.csdn.net/gsycwh/article/details/52972946
- 【刷题】BZOJ 2434 [Noi2011]阿狸的打字机
Description 阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机.打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P'两个字母. 经阿狸研究发现,这个打字机是这样工作的 ...
- 解题:BZOJ 4808 马
题面 以前写过的题,翻出来学习网络流写二分图匹配,因为复杂度更优秀,$Dinic$是$O(sqrt(n)m)$哒~ 原点向左部点连流量为$1$的边,左部点向对应右部点连流量为$1$的边,右部点向汇点连 ...
- Howto run google-chrome as root
Just want to add a permanent solution to the problem: 1. Open google-chrome located in /usr/bin with ...
- JavaScript的变量预解析特性
JavaScript是解释型语言是毋庸置疑的,但它是不是仅在运行时自上往下一句一句地解析的呢?事实上或某种现象证明并不是这样的,通过<JavaScript权威指南>及网上相关资料了解到,J ...