java核心知识点学习----多线程间的数据共享的几种实现方式比较
需求:设计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对象作为一个内部类,将共享数据作为成员变量.
这里用这个方法解决上面的需求,请看下面代码:
package com.amos.concurrent;
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核心知识点学习----多线程间的数据共享和对象独立,ThreadLocal详解
线程内的数据共享与对象独立,举例:张三给李四转钱,开启A线程去执行转钱这个动作,刚好同时王五给赵六转钱,开启B线程去执行转钱,因为是调用的同样一个动作或者说对象,所以如果不能保证线程间的对象独立,那么 ...
- Java核心知识点学习----多线程中的阻塞队列,ArrayBlockingQueue介绍
1.什么是阻塞队列? 所谓队列,遵循的是先进先出原则(FIFO),阻塞队列,即是数据共享时,A在写数据时,B想读同一数据,那么就将发生阻塞了. 看一下线程的四种状态,首先是新创建一个线程,然后,通过s ...
- Java核心知识点学习----多线程并发之线程间的通信,notify,wait
1.需求: 子线程循环10次,主线程循环100次,这样间隔循环50次. 2.实现: package com.amos.concurrent; /** * @ClassName: ThreadSynch ...
- Java核心知识点学习----多线程 倒计时记数器CountDownLatch和数据交换的Exchanger
本文将要介绍的内容都是Java5中的新特性,一个是倒计时记数器---CountDownLatch,另一个是用于线程间数据交换的Exchanger. 一.CountDownLatch 1.什么是Coun ...
- java核心知识点学习----多线程并发之线程同步
1.什么是线程同步? 多线程编程是很有趣的事情,它很容易出现"错误情况",这种情况不是由编码造成的,它是由系统的线程调度造成的,当使用多个线程来访问同一个数据时,很容易出现&quo ...
- Java核心知识点学习----使用Condition控制线程通信
一.需求 实现线程间的通信,主线程循环3次后,子线程2循环2次,子线程3循环3次,然后主线程接着循环3次,如此循环3次. 即:A->B->C---A->B->C---A-> ...
- Java核心知识点学习----线程中如何创建锁和使用锁 Lock,设计一个缓存系统
理论知识很枯燥,但这些都是基本功,学完可能会忘,但等用的时候,会发觉之前的学习是非常有意义的,学习线程就是这样子的. 1.如何创建锁? Lock lock = new ReentrantLock(); ...
- java核心知识点学习----equals和==的比较、单例模式,饿汉式,饱汉式
最近发现自己学习能力变慢了,想来想去还是发现是因为自己Java基础没有打扎实,接下来的一系列文章将主要记录自己对于Java的最基础知识点的学习. 一.equals和==的比较 先看例子: packag ...
- Java核心知识点学习----线程中的Semaphore学习,公共厕所排队策略
1.什么是Semaphore? A counting semaphore. Conceptually, a semaphore maintains a set of permits. Each acq ...
随机推荐
- 我终于搞清楚为什么谷歌地图获取到的联通3G基站与大家手头的基站表不同了
我终于搞清楚这个问题了,大家使用谷歌地图手机版.MobileTrack以及网优用的FieldTest获取到的WCDMA基站Cellid为什么不是大家手头的CellTrack91或基站表里的数字了... ...
- 物流公司统计按物资类别采购的前二十家sql
2.集团主要的供应商(按物资分类列举前10或20家名单),年采购金额.占比,结算方式,付款周期:(夏) 年份要求是2013年 arap_djfb中的单据日期不是常规的日期类型 需要做这样的转换才可以 ...
- 【原】CSS3的3D动画 ——3D旋转之骰子样式的钟表(2)下.md
之前看到智能社主页的那个骰子样式的钟表,最近研究了一下,虽然没有仔细看他是怎么做的,但是学了css3的动画之后想自己尝试着写一下,用到的原理可能和智能社网站的不太一样,我自己主要用到了css3和js. ...
- view--4种Android获取View宽高的方式
有时我们会有基于这样的需求,当Activity创建时,需要获取某个View的宽高,然后进行相应的操作,但是我们在onCreate,onStart中获取View的大小,获取到的值都是0,只是由于View ...
- xml中的非法字符
今使用Jdom生成xml文件的时候,总是出现0x0,0x8为非法字符,经过搜索,问题原因及解决方法如下: 原因:xml中需要过滤的字符分为两类,一类是不允许出现在xml中的字符,这些字符不在xml的定 ...
- intellJ实用技巧
常用语句 在IntelJ中和Eclipse中稍有不同,在Eclipse中,输入main再按Alt+/即可自动补全main函数,但是在IntellJ中则是输入psvm. 在方法体内部有for循环,在In ...
- centos 7 下安装Nginx
下载Nginx wget nginx.tar.gz http://nginx.org/download/nginx-1.11.3.tar.gz 解压源码 .tar.gz 然后进入目录编译安装 cd n ...
- Aquarium Cycling
http://www.fishyou.com/aquarium-cycling.php Aquarium Cycling Aquarium cycling actually refers to the ...
- 44. Decode Ways && Gray Code
Decode Ways A message containing letters from A-Z is being encoded to numbers using the following ma ...
- cordova-plugin-unionpay
https://github.com/Santino-Wu/cordova-plugin-unionpay