博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java并发编程之:线程共享数据的方式
阅读量:5925 次
发布时间:2019-06-19

本文共 4082 字,大约阅读时间需要 13 分钟。

hot3.png

java并发编程之:线程共享数据的方式

多个线程对共同数据的访问的实现,要根据情况而定

(1)当访问共同的代码的时候:可以使用同一个Runnable对象,这个Runnable对象中有这个共享数据,比如卖*系统就可以这么做。或者这个共享数据封装在一个对象当中,然后对这个对象加锁,也可以实现数据安全访问。

(2)当各个线程访问的代码不同时:这时候要使用不同的Runnable对象,有两种实现方式:

a)将共享数据封装在另一个对象当中,然后将这个对象逐一的转递给各个Runnable对象。操作数据的方法也放进这个对象当中。这样容易实现各个线程对这个数据的同步和共享。

b)将Runnable对象作为某一个类中的内部类,共享数据作为这个外部类的成员变量,每个线程对共享数据的访问也交给外部类的方法,比便对共享数据的互斥和通信。Runnable对象调用外部类的操作这个共享数据的方法。

还有一种方式是a)和b)的结合实现,把共享数据封装到一个对象当中去,这个对象也实现对这个共享数据的操作,这个对象作为外部类的成员变量。然后再创建多个Runnable对象做为内部类,操作这个对象。

一、每个线程执行的代码相同,可以使用同一个Runnable对象

public class SellTicket {    public static void main(String[] args) {        Ticket t = new Ticket();        new Thread(t).start();        new Thread(t).start();    }}class Ticket implements Runnable{    private int ticket = 10;    @Override    public void  run() {        while(ticket>0){            synchronized (this){                if(ticket > 0){                    ticket--;                    System.out.println("当前*数为:"+ticket);                }            }        }    }}

二 1)当各个线程访问的代码不同时:这时候要使用不同的Runnable对象,将共享数据封装在另一个对象当中,然后将这个对象逐一的转递给各个Runnable对象。操作数据的方法也放进这个对象当中。这样容易实现各个线程对这个数据的同步和共享

public class MultiThreadShareData {	public static void main(String[] args) {		ShareData1 data2 = new ShareData1();		new Thread(new MyRunnable1(data2)).start();		new Thread(new MyRunnable2(data2)).start();	}}		class MyRunnable1 implements Runnable{		private ShareData1 data1;		public MyRunnable1(ShareData1 data1){			this.data1 = data1;		}		public void run() {			data1.decrement();					}	}		class MyRunnable2 implements Runnable{		private ShareData1 data1;		public MyRunnable2(ShareData1 data1){			this.data1 = data1;		}		public void run() {			data1.increment();		}	}	class ShareData1 {		private int j = 0;		public synchronized void increment(){			j++;		}				public synchronized void decrement(){			j--;		}	}

二 2)把共享数据封装到一个对象当中去,这个对象也实现对这个共享数据的操作,这个对象作为外部类的成员变量。然后再创建多个Runnable对象做为内部类,操作这个对象

public class MultiThreadShareData {	public static void main(String[] args) {		final ShareData1 data1 = new ShareData1();//现在为局部变量,也可以写成类变量static类型(在main方法外声明)		new Thread(new Runnable(){			@Override			public void run() {				data1.decrement();			}		}).start();		new Thread(new Runnable(){			@Override			public void run() {				data1.increment();			}		}).start();	}}		class MyRunnable1 implements Runnable{		private ShareData1 data1;		public MyRunnable1(ShareData1 data1){			this.data1 = data1;		}		public void run() {			data1.decrement();					}	}		class MyRunnable2 implements Runnable{		private ShareData1 data1;		public MyRunnable2(ShareData1 data1){			this.data1 = data1;		}		public void run() {			data1.increment();		}	}	class ShareData1 {		private int j = 0;		public synchronized void increment(){			j++;		}				public synchronized void decrement(){			j--;		}	}

总结:对于要是下同步互斥的代码要放在不同的方法中,并且放在同一个对象当中,容易实现互斥和通信,并且也有利于日后的维护。这样思路也很清晰。

 

多线程间进行通讯例子:(wait(),notify())

public class TraditionalThreadCommunication {	/**	 * @param args	 */	public static void main(String[] args) {				final Business business = new Business();		new Thread(				new Runnable() {										@Override					public void run() {						for(int i=1;i<=20;i++){							business.sub(i);						}					}				}		).start();		for(int i=1;i<=20;i++){			business.main(i);		}	}}  class Business {	  private boolean bShouldSub = true;	  public synchronized void sub(int i){		  while(!bShouldSub){//建议用while 因为线程有时候会被假唤醒,线程没有被通知的时候被唤醒			  try {				this.wait();			} catch (InterruptedException e) {				e.printStackTrace();			}		  }			for(int j=1;j<=10;j++){				System.out.println("sub thread sequence of " + j + ",loop of " + i);			}		  bShouldSub = false;		  this.notify();	  }	  	  public synchronized void main(int i){		  	while(bShouldSub){		  		try {					this.wait();				} catch (InterruptedException e) {					e.printStackTrace();				}		  	}			for(int j=1;j<=100;j++){				System.out.println("main thread sequence of " + j + ",loop of " + i);			}			bShouldSub = true;			this.notify();	  }  }

锁是上在代表要操作的资源的类内部方法中的,而不是线程代码中的。

synchronized 锁什么对象,wait 和 notify 就作用在什么对象上。否则会报错。

 

 

 

转载于:https://my.oschina.net/LucasZhu/blog/1023387

你可能感兴趣的文章
基于事件驱动的DDD领域驱动设计框架分享(附源代码)
查看>>
Linux备份ifcfg-eth0文件导致的网络故障问题
查看>>
2018年尾总结——稳中成长
查看>>
$resource in AngularJS
查看>>
java虚拟机学习笔记 【1】
查看>>
DUBBO笔记
查看>>
nginx php上传大文件的设置(php-fpm)
查看>>
MySQL 运行状态监控方法
查看>>
vs2008中在解决方案资源管理器查看当前打开文件
查看>>
ubuntu14.04 鼠标闪烁问题
查看>>
jQuery Lightbox(balupton版)图片展示插件demo
查看>>
Elasticsearch集群的简单搭建
查看>>
SCRT-SSH传输文件
查看>>
Python非常cool的svg格式chart生成库pygal
查看>>
Telnet部署与启动 windows&&linux
查看>>
行列式的乘法定理
查看>>
有1000瓶水,3个瓶子可以再换1瓶,一共可以喝多少瓶?
查看>>
Search in Rotated Sorted Array ||
查看>>
NUC_HomeWork1 -- POJ2067(最短路)
查看>>
卸载mysql
查看>>