Android多线程研究(6)——多线程之间数据隔离
在上一篇《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)——多线程之间数据隔离的更多相关文章
- Android中实现跨app之间数据的暴露与接收
例如一个小项目:实现单词本的添加单词等功能 功能:不同的方式实现跨app之间数据的暴露与接收 暴露端app:实现单词的添加(Word.Translate),增删改查: 接收端app:模糊查询,得到暴露 ...
- 【转】Android进阶2之Activity之间数据交流(onActivityResult的用法)----不错
原文网址:http://blog.csdn.net/sjf0115/article/details/7387467 主要功能: 在一个主界面(主Activity)上能连接往许多不同子功能模块(子Act ...
- Android进阶2之Activity之间数据交流(onActivityResult的用法) (转载)
转自:http://blog.csdn.net/sjf0115/article/details/7387467 主要功能: 在一个主界面(主Activity)上能连接往许多不同子功能模块(子Activ ...
- Python进阶----进程间数据隔离, join阻塞等待, 进程属性, 僵尸进程和孤儿进程, 守护进程
Python进阶----进程间数据隔离, join阻塞等待, 进程属性, 僵尸进程和孤儿进程, 守护进程 一丶获取进程以及父进程的pid 含义: 进程在内存中开启多个,操作系统如何区分这些进程, ...
- 无废话Android之smartimageview使用、android多线程下载、显式意图激活另外一个activity,检查网络是否可用定位到网络的位置、隐式意图激活另外一个activity、隐式意图的配置,自定义隐式意图、在不同activity之间数据传递(5)
1.smartimageview使用 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android&q ...
- ThreadLocal 多线程并发,数据隔离
ThreadLocal: 创建一个线程本地变量. 本质:在ThreadLocal类中有一个Map,用于存储每一个线程的变量的副本. 优点:既实现多线程并发,游兼顾数据的安全性. 区别:Synchro ...
- VC中利用多线程技术实现线程之间的通信
当前流行的Windows操作系统能同时运行几个程序(独立运行的程序又称之为进程),对于同一个程序,它又可以分成若干个独立的执行流,我们称之为线程,线程提供了多任务处理的能力.用进程和线程的观点来研究软 ...
- Android:Activity+Fragment及它们之间的数据交换.
Android:Activity+Fragment及它们之间的数据交换 关于Fragment与Fragment.Activity通信的四种方式 比较好一点的Activity+Fragment及它们之间 ...
- Android 在不同Actitity之间数据传递
本文实现一个简易的人品计算器来实践在不同Actitity之间数据传递 intent的数据传递 从A界面打开B界面 把A界面的数据传递给B界面 1. intent.setData(uri) -- int ...
随机推荐
- codeforces111D. Petya and Coloring(组合数学,计数问题)
传送门: 解题思路: 要求一条直线分割矩阵时左右颜色数一样,那么就说明一个问题.直线左右移动时是不会改变左右矩阵的颜色集合的.所以说明:2~m-1列的颜色集一定属于第一列与第m列颜色集的交集.而且第一 ...
- caioj 1063 动态规划入门(一维一边推1:美元和马克)
这道题一开始我是这么想的 最后的答案肯定是某次的马克换回来的,但这个该怎么确定?? 实际上应该把范围缩小,只看最后一次和倒数第二次之间有什么联系. 可以发现,只有两种可能,最后一天换或者不换.换的话就 ...
- 【Codeforces Round #460 (Div. 2) A】 Supermarket
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 就是让你求m*(ai/bb)的最小值 [代码] #include <bits/stdc++.h> #define dou ...
- Linux学习总结(1)——Linux命令大全完整版
Linux命令大全完整版 目 录I 1. linux系统管理命令1 adduser1 chfn(change finger information)1 chsh(change shell)1 d ...
- Linux下经常使用的C/C++开源Socket库
1. Linux Socket Programming In C++ : http://tldp.org/LDP/LG/issue74/tougher.html 2. ACE: h ...
- OpenCASCADE Face Normals
OpenCASCADE Face Normals eryar@163.com Abstract. 要显示一个逼真的三维模型,其顶点坐标.顶点法向.纹理坐标这三个信息必不可少.本文主要介绍如何在Open ...
- tomcat 分别在window 和 Linux上配置SSL-安全问题
公司项目收尾后.通过压力測试后的安全測试.安全測试后中,对于网络传输中数据加密问题存在安全隐患. 须要配置SSL. 简介下SSL协议:SSL或者Secure Socket Layer,是一种同意web ...
- jquery插件库http://www.jq22.com/
http://www.jq22.com/ http://www.jq22.com/jquery/%E5%8A%A0%E8%BD%BD http://www.jq22.com/jquery/%E5%BC ...
- 62.C++文件操作list实现内存检索,实现两千万数据秒查
1 #include <iostream> #include <fstream> #include <cstdlib> #include <string> ...
- 动态引入js代码
var _hmt = _hmt || []; (function() { var hm = document.createElement("script"); hm.src = & ...