【多线程 3】多线程间的变量共享方式

上篇博客说到了多线程的创建方式,本篇博客说说自己对于多个线程间的共享变量的理解。

一、概述

首先,分析集中不同的变量共享场景:

1,多个线程执行同样的代码

在这种情况下,可以使用同一个Runnable对象(看上一篇博客,这是一种创建线程的方式)将需要共享的数据,植入这个Runnable对象里面。例如买票系统,余票是需要共享的,不过在这样做的时候,我想还应该加上synchronized关键字修饰!

2,多个线程执行的代码不一样

在这种情况下,就两种思路可以实现(这里参考张孝祥老师的观点)

其一:将共享数据封装再另外一个对象中,然后将这个对象逐一传递给各个Runnable对象。每个线程对共享数据的操作方法也分配到那个对象身上去完成,这样容易实现对改数据进行的各个操作的互斥和通信。

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

组合:将共享数据封装再另外一个对象中,每个线程对共享数据的操作方法也分配到那个对象身上去完成,对象作为这个外部类中的成员变量或方法中的局部变量,每个线程的Runnable对象作为外部类中的成员内部类或局部内部类。(示例代码所使用的方法),总之,要同步互斥的几段代码最好是分别放在几个独立的方法中,这些方法再放在同一个类中,这样比较好容易实现它们之间的同步互斥通信

3,简单粗暴的方式

在程序中,定义一个static变量


二、代码示例

<span style="font-family:KaiTi_GB2312;font-size:18px;">package Angel;

public class MultiThreadShareData {

	private static ShareData1 data1 = new ShareData1();
	
	public static void main(String[] args) {
		ShareData1 data2 = new ShareData1();
		new Thread(new MyRunnable1(data2)).start();//减
		new Thread(new MyRunnable2(data2)).start();//加
		
		final ShareData1 data1 = new ShareData1();
		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++;
			System.out.println(j);
		}
		
		public synchronized void decrement(){
			j--;
			System.out.println(j);
		}
	}</span>


三、总结

实现共享数据,不只有这个方式,还应该有已经封装好的更为方便的方式,下篇博客接着介绍。在说到这个基础知识点的时候,突然想到了另外一个关于多线程的基本点,就是在使用多线程的时候,我们会常用到wait()和sleep()方法,那么这两种方法到底有什么区别呢?先看一下线程的状态图:



简单说来:sleep()方法是属于Thread类中的。而wait()方法是属于Object类中的。


sleep()方法导致了程序暂停执行指定的时间,让出cpu该其他线程,但是他的监控状态依然保持者,当指定的时间到了又会自动恢复运行状态。在调用sleep()方法的过程中,线程不会释放对象锁。
当调用wait()方法的时候,线程会放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象调用notify()方法后本线程才进入对象锁定池准备,获取对象锁进入运行状态。


原文地址:https://www.cnblogs.com/hhx626/p/7534631.html