java线程共享数据_Java线程——线程之间的数据共享

在 Java 传统线程机制中的共享数据方式,大致可以简单分两种情况:

➢ 多个线程行为一致,共同操作一个数据源。也就是每个线程执行的代码相同,可以使用同一个 Runnable 对象,这个 Runnable 对象中有那个共享数据,例如,卖票系统就可以这么做。

➢ 多个线程行为不一致,共同操作一个数据源。也就是每个线程执行的代码不同,这时候需要用不同的Runnable 对象。例如,银行存取款。

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

如果每个线程执行的代码相同,可以使用同一个 Runnable 对象,这个 Runnable 对象中有那个共享数据,例如,买票系统就可以这么做。

packagecom.itheima.gan;

//买票系统

//共享数据类

classShareDate{private int num=10; //10张票

public synchronized voidinc() {

num++;

System.out.println(Thread.currentThread().getName()+

": invoke inc method num="+num);try{//线程休眠1s

Thread.sleep(1000);

}catch(InterruptedException e) {

e.printStackTrace();

}

}

}/*** 多线程类

*@author12428

**/

public class RunnableCusToInc implementsRunnable{privateShareDate shareDate;//构造方法,将数据传递进去

publicRunnableCusToInc(ShareDate shareDate) {this.shareDate=shareDate;

}//线程应该做的事

@Overridepublic voidrun() {for(int i=0;i<5;i++) {

shareDate.inc();

}

}public static voidmain(String[] args) {

ShareDate shareDate=newShareDate();for(int i=0;i<4;i++) {new Thread(new RunnableCusToInc(shareDate),"线程"+i).start();

}

}

}

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

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

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

packagecom.itheima.gan;class RunnableCusToDec implementsRunnable {privateShareDate1 shareDate;publicRunnableCusToDec(ShareDate1 shareDate) {this.shareDate =shareDate;

}

@Overridepublic voidrun() {for (int i = 0; i < 5; i++) {

shareDate.dec();

}

}

}public class RunnableCusToInc2 implementsRunnable {privateShareDate1 shareDate;publicRunnableCusToInc2(ShareDate1 shareDate) {this.shareDate =shareDate;

}

@Overridepublic voidrun() {for (int i = 0; i < 5; i++) {

shareDate.inc();

}

}public static voidmain(String[] args) {

ShareDate1 shareDate1=newShareDate1();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();

}

}

}

}/** 共享数据类*/

classShareDate1 {private int num = 10;public synchronized voidinc() {

num++;

System.out.println(Thread.currentThread().getName()+ ": invoke inc method num=" +num);try{

Thread.sleep(1000);

}catch(InterruptedException e) {

e.printStackTrace();

}

}public synchronized voiddec() {

num--;

System.err.println(Thread.currentThread().getName()+ ": invoke dec method num =" +num);try{

Thread.sleep(1000);

}catch(InterruptedException e) {

e.printStackTrace();

}

}

}

运行结果如图:

82ff9b642db78c43950676a77cd085e1.png

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

packagecom.itheima.gan;public classRunnableTest {public static voidmain(String[] args) {//公共数据

final ShareDate2 shareDate=newShareDate2();for(int i=0;i<4;i++) {if(i%2==0) {new Thread(newRunnable() {

@Overridepublic voidrun() {for(int i=0;i<5;i++) {

shareDate.inc();

}

}

},"Thread "+i).start();

}else{new Thread(newRunnable() {

@Overridepublic voidrun() {for(int i=0;i<5;i++) {

shareDate.dec();

}

}

}).start();

}

}

}

}//公共数据类

classShareDate2{private int num=10;public synchronized voidinc() {

num++;

System.err.println(Thread.currentThread().getName()+" : invoke inc method num = "+num);try{

Thread.sleep(1000);

}catch(InterruptedException e) {

e.printStackTrace();

}

}public synchronized voiddec() {

num--;

System.out.println(Thread.currentThread().getName()+" : invoke dec method num = "+num);try{

Thread.sleep(1000);

}catch(InterruptedException e) {

e.printStackTrace();

}

}

}

运行结果如图:

c41ef6e52c43b08a2dbc44927f3424f4.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值