在 Java 传统线程机制中的共享数据方式,大致可以简单分两种情况:
➢ 多个线程行为一致,共同操作一个数据源。也就是每个线程执行的代码相同,可以使用同一个 Runnable 对象,这个 Runnable 对象中有那个共享数据,例如,卖票系统就可以这么做。
➢ 多个线程行为不一致,共同操作一个数据源。也就是每个线程执行的代码不同,这时候需要用不同的Runnable 对象。例如,银行存取款。 
 
实例1:多个线程行为一致共同操作一个数据
 
  如果每个线程执行的代码相同,可以使用同一个 Runnable 对象,这个 Runnable 对象中有那个共享数据,例如,买票系统就可以这么做。

package com.itheima.gan;
//买票系统
//共享数据类
class ShareDate{
private int num=10; //10张票 public synchronized void inc() {
num++;
System.out.println(Thread.currentThread().getName()+
": invoke inc method num="+num);
try {
//线程休眠1s
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} /**
* 多线程类
* @author 12428
*
*/
public class RunnableCusToInc implements Runnable{ private ShareDate shareDate;
//构造方法,将数据传递进去
public RunnableCusToInc(ShareDate shareDate) {
this.shareDate=shareDate;
}
//线程应该做的事
@Override
public void run() {
for(int i=0;i<5;i++) {
shareDate.inc();
} } public static void main(String[] args) {
ShareDate shareDate=new ShareDate(); for(int i=0;i<4;i++) {
new Thread(new RunnableCusToInc(shareDate),"线程"+i).start();
}
}
}

实例2:多个线程行为不一致共同操作一个数据 

如果每个线程执行的代码不同,这时候需要用不同的 Runnable 对象,有如下两种方式来实现这些 Runnable 对象之间的数据共享

(1)将共享的数据放到一个对象中,在把这个对象逐一传递给各个Runnable对象,每个线程对该数据的操作也放在这个对象的不同方法中,这样说实现容易针对对该数据进行的各个操作的互斥和通信。

package com.itheima.gan;

class RunnableCusToDec implements Runnable {
private ShareDate1 shareDate; public RunnableCusToDec(ShareDate1 shareDate) {
this.shareDate = shareDate;
} @Override
public void run() {
for (int i = 0; i < 5; i++) {
shareDate.dec();
}
}
} public class RunnableCusToInc2 implements Runnable { private ShareDate1 shareDate; public RunnableCusToInc2(ShareDate1 shareDate) {
this.shareDate = shareDate;
} @Override
public void run() {
for (int i = 0; i < 5; i++) {
shareDate.inc();
}
} public static void main(String[] args) {
ShareDate1 shareDate1=new ShareDate1();
for(int i=0;i<4;i++) {
if(i%2==0) {
new Thread(new RunnableCusToInc2(shareDate1),"Thread"+i).start();
}else {
new Thread(new RunnableCusToDec(shareDate1),"Thread"+i).start();
}
}
}
} /*
* 共享数据类
*/
class ShareDate1 {
private int num = 10; public synchronized void inc() {
num++;
System.out.println(Thread.currentThread().getName() + ": invoke inc method num=" + num); try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
} public synchronized void dec() {
num--;
System.err.println(Thread.currentThread().getName() + ": invoke dec method num =" + num);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

  运行结果如图:

(2)将这些 Runnable 对象作为某一个类中的内部类,共享数据作为这个外部类中的成员变量,每个线程对共享数据的操作方法也分配给外部类,以便实现对共享数据进行的各个操作的互斥和通信,作为内部类的各个Runnable 对象调用外部类的这些方法。

package com.itheima.gan;

public class RunnableTest {
public static void main(String[] args) {
//公共数据
final ShareDate2 shareDate=new ShareDate2();
for(int i=0;i<4;i++) {
if(i%2==0) {
new Thread(new Runnable() { @Override
public void run() {
for(int i=0;i<5;i++) {
shareDate.inc();
} }
},"Thread "+i).start();
}else {
new Thread(new Runnable() { @Override
public void run() {
for(int i=0;i<5;i++) {
shareDate.dec();
} }
}).start();
}
}
}
} //公共数据类
class ShareDate2{ private int num=10; public synchronized void inc() {
num++;
System.err.println(Thread.currentThread().getName()+" : invoke inc method num = "+num);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
} public synchronized void dec() {
num--;
System.out.println(Thread.currentThread().getName()+" : invoke dec method num = "+num);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
} }

  运行结果如图:

Java线程——线程之间的数据共享的更多相关文章

  1. 并发编程8 线程的创建&验证线程之间数据共享&守护线程&线程进程效率对比&锁(死锁/递归锁)

    1.线程理论以及线程的两种创建方法 2.线程之间是数据共享的与join方法 3.多线程和多进程的效率对比 4.数据共享的补充线程开启太快 5.线程锁 互斥锁 同步锁 6.死锁现象和递归锁 7.守护线程 ...

  2. java 多线程 day05 线程范围内的数据共享

    import java.util.HashMap;import java.util.Map;import java.util.Random;/** * Created by chengtao on 1 ...

  3. Java多线程——线程之间的协作

    Java多线程——线程之间的协作 摘要:本文主要学习多线程之间是如何协作的,以及如何使用wait()方法与notify()/notifyAll()方法. 部分内容来自以下博客: https://www ...

  4. Java多线程——线程之间的同步

    Java多线程——线程之间的同步 摘要:本文主要学习多线程之间是如何同步的,如何使用volatile关键字,如何使用synchronized修饰的同步代码块和同步方法解决线程安全问题. 部分内容来自以 ...

  5. Java多线程——线程范围内共享变量

    多个线程访问共享对象和数据的方式 1.如果每个线程执行的代码相同,可以使用同一个Runnable对象,这个Runnable对象中有那个共享数据,例如,买票系统就可以这么做. package java_ ...

  6. java中线程队列BlockingQueue的用法

    在新增的Concurrent包中,BlockingQueue很好的解决了多线程中,如何高效安全“传输”数据的问题.通过这些高效并且线程安全的队列类,为我们快速搭建高质量的多线程程序带来极大的便利.本文 ...

  7. Java并发——线程安全、线程同步、线程通信

    线程安全 进程间"共享"对象 多个“写”线程同时访问对象. 例:Timer实例的num成员,即add()方法是用的次数.即Timer实例是资源对象. class TestSync ...

  8. Java多线程——线程范围内共享变量和ThreadLocal

    多个线程访问共享对象和数据的方式 1.如果每个线程执行的代码相同,可以使用同一个Runnable对象,这个Runnable对象中有那个共享数据,例如,买票系统就可以这么做. package java_ ...

  9. java之线程

    java之线程 一:线程: 线程是什么呢?线程,有时被称为轻量级进程是程序执行流的最小单元.一个标准的线程由线程ID,当前指令指针(PC),寄存器集合和堆栈组成.另外,线程是进程中的一个实体,是被系统 ...

随机推荐

  1. GeneWise

    GeneWise是用于将蛋白质序列进行同源预测的软件

  2. LeetCode455 分发饼干(简单贪心—Java优先队列简单应用)

    题目: 假设你是一位很棒的家长,想要给你的孩子们一些小饼干.但是,每个孩子最多只能给一块饼干.对每个孩子 i ,都有一个胃口值 gi ,这是能让孩子们满足胃口的饼干的最小尺寸:并且每块饼干 j ,都有 ...

  3. Golang的标准命令简述

    Golang的标准命令简述 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. Go本身包含了大量用于处理Go程序的命令和工具.go命令就是其中最常见的一个,它有许多子命令,接下来就跟随 ...

  4. Visual Studio Code 断点调试配置方法(请按我的步骤 一定可以做到)

    1 visual studio code 的 extentions 里安装插件 debugger for chrome2 devtool: 'eval-source-map', cacheBustin ...

  5. JQuery 动画实现

    $(this.div_wrong).show().css({width:"0px", height:"0px"})    .animate({width:&qu ...

  6. 利用vim查看日志,快速定位问题《转载》

    利用vim查看日志,快速定位问题 链接:https://www.cnblogs.com/abcwt112/p/5192944.html

  7. SpringBoot 系列教程之事务隔离级别知识点小结

    SpringBoot 系列教程之事务隔离级别知识点小结 上一篇博文介绍了声明式事务@Transactional的简单使用姿势,最文章的最后给出了这个注解的多个属性,本文将着重放在事务隔离级别的知识点上 ...

  8. 111-PHP类变量之间的赋值标识为同一个对象

    <?php class mao{ //定义猫类 public $age=0; //定义多个属性并初始化 public $weight=50; public $color='white'; } $ ...

  9. python_re正则表达

    re模块就本质而言,正则表达式(或RE)是一种小型的.高度专业化的编程语言,(在python中)它内嵌在Python中,并通过re模块实现,正则表达式模块被编译成一系列的字节码,然后由用C编写的匹配引 ...

  10. 【Android】家庭记账本手机版开发报告二

    一.说在前面 昨天 完成了对记账本的账单的增删 今天 完善昨天的框架结构( 1.引入ViewModel管理数据.使MainActive 只管理界面.不再管数据了 2.引入AsyncTask.后台执行. ...