在上一篇《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;
}
}
}

执行结果:

从上面我们能够看到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());
}
}
}

输出结果:

上面代码中我们用一个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();
}
}
}

执行结果:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZGF3YW5nYW5iYW4=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="" />

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

Android多线程研究(6)——多线程之间数据隔离的更多相关文章

  1. Android中实现跨app之间数据的暴露与接收

    例如一个小项目:实现单词本的添加单词等功能 功能:不同的方式实现跨app之间数据的暴露与接收 暴露端app:实现单词的添加(Word.Translate),增删改查: 接收端app:模糊查询,得到暴露 ...

  2. 【转】Android进阶2之Activity之间数据交流(onActivityResult的用法)----不错

    原文网址:http://blog.csdn.net/sjf0115/article/details/7387467 主要功能: 在一个主界面(主Activity)上能连接往许多不同子功能模块(子Act ...

  3. Android进阶2之Activity之间数据交流(onActivityResult的用法) (转载)

    转自:http://blog.csdn.net/sjf0115/article/details/7387467 主要功能: 在一个主界面(主Activity)上能连接往许多不同子功能模块(子Activ ...

  4. Python进阶----进程间数据隔离, join阻塞等待, 进程属性, 僵尸进程和孤儿进程, 守护进程

    Python进阶----进程间数据隔离, join阻塞等待, 进程属性, 僵尸进程和孤儿进程, 守护进程 一丶获取进程以及父进程的pid 含义:    进程在内存中开启多个,操作系统如何区分这些进程, ...

  5. 无废话Android之smartimageview使用、android多线程下载、显式意图激活另外一个activity,检查网络是否可用定位到网络的位置、隐式意图激活另外一个activity、隐式意图的配置,自定义隐式意图、在不同activity之间数据传递(5)

    1.smartimageview使用 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android&q ...

  6. ThreadLocal 多线程并发,数据隔离

    ThreadLocal:  创建一个线程本地变量. 本质:在ThreadLocal类中有一个Map,用于存储每一个线程的变量的副本. 优点:既实现多线程并发,游兼顾数据的安全性. 区别:Synchro ...

  7. VC中利用多线程技术实现线程之间的通信

    当前流行的Windows操作系统能同时运行几个程序(独立运行的程序又称之为进程),对于同一个程序,它又可以分成若干个独立的执行流,我们称之为线程,线程提供了多任务处理的能力.用进程和线程的观点来研究软 ...

  8. Android:Activity+Fragment及它们之间的数据交换.

    Android:Activity+Fragment及它们之间的数据交换 关于Fragment与Fragment.Activity通信的四种方式 比较好一点的Activity+Fragment及它们之间 ...

  9. Android 在不同Actitity之间数据传递

    本文实现一个简易的人品计算器来实践在不同Actitity之间数据传递 intent的数据传递 从A界面打开B界面 把A界面的数据传递给B界面 1. intent.setData(uri) -- int ...

随机推荐

  1. Tensorflow 函数学习笔记

    A: A:## tf.argmax(A, axis).eval() 输出axis维度上最大的数的索引 axis=0:列,axis=1:行 A:## tf.add(a,b)  创建a+b的计算图 A:# ...

  2. Swift学习笔记(2)--元组(Tuples)、Optional(可选值)、(Assertions)断言

    1.Tuples(元组) 元组是多个值组合而成的复合值.元组中的值可以是任意类型,而且每一个元素的类型可以是不同的. 1>定义:使用()包含所有元素,用逗号分开,也可以对每个元素做命名 let ...

  3. 从设计到实现,一步步教你实现Android-Universal-ImageLoader-辅助类

    通过前面几篇博文.我们分析了 AUI 的缓存.工具类.显示与载入这几个方面的代码.今天呢,我们继续研究 AUI 的源代码,学习当中的核心辅助工具类. 希望大家能在里面学到东西哈. Download 要 ...

  4. ORA-4031错误 解决方法

    遇到ORA-4031错误时.你的心里会不会发怵?ORA-4031非常easy导致数据库出现异常崩溃,当Oracle的核心进程无法获得共享池内存时.它们会把数据库异常宕掉.当然,ORA-4031就像黄灯 ...

  5. WebGoat学习(一)--环境搭建

    参考https://www.owasp.org/index.php/Category:OWASP_WebGoat_Project https://github.com/WebGoat/WebGoat ...

  6. C#接口,类,集成

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  7. 暑假集训-二分图,网络流,2-SAT

    匈牙利算法DFS bool dfs(int u){ ; i <= n; i++){ if(a[u][i] && !visit[i]){ visit[i] = true; || d ...

  8. 用SSL保Samba安全

    用SSL保Samba安全          在企业中用Samba做为文件服务器是非常容易的事了,那如何保证存储数据的安全,如何保证数据传输的安全呢?我以前介绍过通过Samba安全级别和加装防病毒软件在 ...

  9. mybatis的XML返回值类型报错

    昨天项目里一直报错说是一个文件里的返回值java.util.hashmap不对,然后去定位这个文件发现并没有问题,后来在全局搜索的帮助下查找了返回值类型为resultMap的文件里看到写的代码里有: ...

  10. 【DRF权限】

    目录 权限的详细用法 我们都听过权限,那么权限到底是做什么的呢. 我们都有博客,或者去一些论坛,一定知道管理员这个角色, 比如我们申请博客的时候,一定要向管理员申请,也就是说管理员会有一些特殊的权利, ...