首页 > 移动平台 > 详细

Android多线程研究(6)——多线程之间数据隔离

时间:2014-06-20 11:19:30      阅读:394      评论:0      收藏:0      [点我收藏+]

在上一篇《Android多线程研究(5)——线程之间共享数据》中对线程之间的数据共享进行了学习和研究,这一篇我们来看看如何解决多个线程之间的数据隔离问题,什么是数据隔离呢?比如说我们现在开启了两个线程,这两个线程都要同时给同一个全局变量data赋值,各个线程操作它赋值后的变量数据,这里就需要用到隔离。先看一段代码:

import java.util.Random;


public class ThreadLocalTest {
	private static int data = 0;
	public static void main(String[] args) {
		for(int i=0; i<2; i++){
			new Thread(new Runnable() {
				
				@Override
				public void run() {
					data = new Random().nextInt();
					System.out.println(Thread.currentThread().getName() +
							" has put data: " + data);
					new A().get();
					new B().get();
				}
			}).start();
		}
	}
	
	static class A{
		public int get(){
			System.out.println("A from " + Thread.currentThread().getName() +
					" has get data: " + data);
			return data;
		}
	}
	
	static class B{
		public int get(){
			System.out.println("B from " + Thread.currentThread().getName() +
					" has get data: " + data);
			return data;
		}
	}
}
运行结果:

bubuko.com,布布扣

从上面我们可以看到Thread-0和Thread-1都在操作变量data,但是两个线程之间没有做到对数据操作的隔离,所以输出结果中两个线程共用了一个data变量。

我们将上面代码修改如下:

import java.util.HashMap;
import java.util.Map;
import java.util.Random;


public class ThreadLocalTest {
	//private static int data = 0;
	private static Map<Thread, Integer> map = new HashMap<Thread, Integer>();
	public static void main(String[] args) {
		for(int i=0; i<2; i++){
			new Thread(new Runnable() {
				
				@Override
				public void run() {
					//data = new Random().nextInt();
					int data = new Random().nextInt();
					map.put(Thread.currentThread(), data);
					System.out.println(Thread.currentThread().getName() +
							" has put data: " + data);
					new A().get();
					new B().get();
				}
			}).start();
		}
	}
	
	static class A{
		public int get(){
			System.out.println("A from " + Thread.currentThread().getName() +
					" has get data: " + map.get(Thread.currentThread()));
			return map.get(Thread.currentThread());
		}
	}
	
	static class B{
		public int get(){
			System.out.println("B from " + Thread.currentThread().getName() +
					" has get data: " + map.get(Thread.currentThread()));
			return  map.get(Thread.currentThread());
		}
	}
}
输出结果:

bubuko.com,布布扣

上面代码中我们用一个Map集合隔离了线程对data数据的操作,其实相当于创建了一个data数据的备份(双份的data)实现了线程之间数据的隔离,其实早在Java 1.2就引入了一个用来支持线程数据隔离的类(java.lang.ThreadLocal),下面我们来看看如何使用ThreadLocal实现线程之间的数据隔离。

ThreadLocal中的三个方法:‘

get() :返回当前线程的线程局部变量副本

protected initialValue() :返回该线程局部变量的当前线程的初始值

void set(Object value) :设置当前线程的线程局部变量副本的值

其中initialValue方法是为子类写的方法,在一个线程第一次调用get()或者set()方法时执行,并且仅执行一次。

import java.util.Random;


public class ThreadLocalTest {
	//private static int data = 0;
	//private static Map<Thread, Integer> map = new HashMap<Thread, Integer>();
	private static ThreadLocal<Integer> tl = new ThreadLocal<Integer>();
	public static void main(String[] args) {
		for(int i=0; i<2; i++){
			new Thread(new Runnable() {
				
				@Override
				public void run() {
					//data = new Random().nextInt();
					int data = new Random().nextInt();
					//map.put(Thread.currentThread(), data);
					tl.set(data);
					System.out.println(Thread.currentThread().getName() +
							" has put data: " + data);
					new A().get();
					new B().get();
				}
			}).start();
		}
	}
	
	static class A{
		public int get(){
			System.out.println("A from " + Thread.currentThread().getName() +
					" has get data: " + tl.get());
			return tl.get();
		}
	}
	
	static class B{
		public int get(){
			System.out.println("B from " + Thread.currentThread().getName() +
					" has get data: " + tl.get());
			return  tl.get();
		}
	}
}
运行结果:

bubuko.com,布布扣

上面代码明显少了很多,其实ThreadLocal中底层也是用Map来存储变量副本实现的。




Android多线程研究(6)——多线程之间数据隔离,布布扣,bubuko.com

Android多线程研究(6)——多线程之间数据隔离

原文:http://blog.csdn.net/dawanganban/article/details/28469777

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!