多线程与并发----共享数据的方式探讨 红太狼 2021-09-15 10:04 266阅读 0赞 ** 如果每个线程执行的代码相同**,可以使用同一个Runnable对象,这个Runnable对象中有那个共享数据,比如,卖票系统就可以这么做。 public class MultiThreadShareData { public static void main(String[] args) { ShareData1 data1=new ShareData1(); new Thread(data1).start(); new Thread(data1).start(); } } class ShareData1 implements Runnable{ private int count=100; public void run() { while(true){ count--; } } private int j=0; public synchronized void increment(){ j++; } public synchronized void decrement(){ j--; } } **如果每个线程执行的代码不同**,这时候需要不同的Runnable对象,有如下两种方式来实现这些Runnable对象之间的数据共享: 1、将共享数据封装在另一个对象中,然后将这个对象逐一传递给各个Runnable对象。每个线程对共享数据的操作方法也分配到那个对象身上完成,这样容易实现针对该数据进行的各个操作的互斥和通信。 > public class MultiThreadShareData { > > public static void main(String[] args) { > final ShareData1 data1=new ShareData1(); > new Thread(new MyRunnable1(data1)).start(); > new Thread(new MyRunnable2(data1)).start(); > } > } > > class MyRunnable1 implements Runnable{ > private ShareData1 data1; > private int count=100; > public MyRunnable1(ShareData1 data1){ > this.data1=data1; > } > public void run() { > while(count!=0){ > count--; > data1.decrement(); > } > > } > } > > class MyRunnable2 implements Runnable{ > private ShareData1 data1; > private int count=100; > public MyRunnable2(ShareData1 data1){ > this.data1=data1; > } > public void run() { > while(count!=0){ > count--; > data1.decrement(); > } > } > } > > class ShareData1{ > > private int j=0; > public synchronized void increment(){ > j++; > System.out.println("A "+Thread.currentThread().getName()+":"+j); > } > > public synchronized void decrement(){ > j--; > System.out.println("B "+Thread.currentThread().getName()+":"+j); > } > } > > > 2、将这些Runnable对象作为某一个类中的内部类,共享数据作为这个外部类中的成员变量,每个线程对共享数据的操作方法也分配给外部类,以便实现对共享数据进行的各个操作的互斥和通信,作为内部类的各个Runnable对象调用外部类的这些方法。 > public class MultiThreadShareData { > > private static ShareData1 data1=new ShareData1();//作为成员变量 > > public static void main(String[] args) { > new Thread(new Runnable() { > private int count=10; > public void run() { > while(count!=0){ > count--; > data1.decrement(); > } > } > }).start(); > > new Thread(new Runnable() { > private int count=10; > public void run() { > while(count!=0){ > count--; > data1.increment(); > } > } > }).start(); > > } > } > > class ShareData1{ > > private int j=0; > public synchronized void increment(){ > j++; > System.out.println("A "+Thread.currentThread().getName()+":"+j); > } > > public synchronized void decrement(){ > j--; > System.out.println("B "+Thread.currentThread().getName()+":"+j); > } > } 3、上面两种方式的组合:将共享数据封装在另外一个对象中,每个线程对共享数据的操作方法也分配到那个对象身上完成,对象作为这个外部类中的成员变量或方法中的局部变量,每个线程的Runnable对象作为外部类中的成员内部类或局部内部类。 总之,要同步互斥的几段代码最好是分别放在几个独立的方法中,这些方法在放在同一个类中,这样容易实现它们之间的同步互斥和通信。 **实例:** 设计4个线程,其中两个线程每次对 j 增加1,另外两个线程对 j 每次减少1,写出程序。 > public class ThreadTest1 > { > private int j; > public static void main(String args[]){ > ThreadTest1 tt=new ThreadTest1(); > Inc inc=tt.new Inc(); > Dec dec=tt.new Dec(); > for(int i=0;i<2;i++){ > Thread t=new Thread(inc); > t.start(); t=new Thread(dec); > t.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 Inc implements Runnable{ > public void run(){ > for(int i=0;i<100;i++){ > inc(); > } > } > } > class Dec implements Runnable{ > public void run(){ > for(int i=0;i<100;i++){ > dec(); > } > } > } > } > > >
还没有评论,来说两句吧...