多线程与并发----共享数据的方式探讨


    如果每个线程执行的代码相同,可以使用同一个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(); 
       } 
   } 
} 
} 

猜你喜欢

转载自blog.csdn.net/pengzhisen123/article/details/80279747