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 ...
随机推荐
- 转载——利用C#自带组件强壮程序日志
利用C#自带组件强壮程序日志 在项目正式上线后,如果出现错误,异常,崩溃等情况 我们往往第一想到的事就是查看日志 所以日志对于一个系统的维护是非常重要的 声明 正文中的代码只是一个栗子,一个非常简 ...
- 慢慢人生路,学点Jakarta基础-集合类
动态改变内存 因为数组在存储之前需要先申请一块连续的内存空间并且在编译的收就必须确定好它的空间大小,在运行时控件的大小无法再随着需求的改变而改变,极易出现越界的情况,数据少时又会造成内存空间浪费. 主 ...
- ssh框架的总结
一.spring:是基础,可以管理对象,也可以通过关键对象管理另一个框架.但是首先应该明确spring并不是只能应用于web方面,而是可以应用在一般的java项目中.只是如果在web环境下使用需要在w ...
- OpenCV —— 写入AVI视频文件
打开视频文件,对每一帧进行极坐标变换,然后将转换生成的图像序列写入视频文件中 #include "cv.h" #include "highgui.h" int ...
- sessionStorage的使用方法
本篇是关于sessionStorage的使用方法的介绍,简单几行代码,实现sessionStorage,请大家查阅 (1)在需要设置sessionStorage的页面写如下代码可以存入sessionS ...
- 洛谷 P1400 塔
P1400 塔 题目描述 有N(2<=N<=600000)块砖,要搭一个N层的塔,要求:如果砖A在砖B上面,那么A不能比B的长度+D要长.问有几种方法,输出 答案 mod 10000000 ...
- iOS_31_cocos2d_微信飞机
终于效果图: 纹理素材 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcHJlX2VtaW5lbnQ=/font/5a6L5L2T/fontsize/400 ...
- 使用缓存Memcache存储更新微信access token
关键字:Memcache access_token 更新 存储 7200 本文介绍如何使用缓存Memcache存储及更新 access token的方法. 一.Access Token access_ ...
- Java学习笔记四
1.简介.进程和线程:简单的说就是进程负责为程序开辟内存空间,线程负责具体的执行单元(执行路径). 一个进程中可以有多个执行路径,称为多线程.CPU一次只能执行一个进程,但是一个进程内部可以有多个线程 ...
- DG查看恢复进度
查看恢复进度 (1)查看进程的活动状态 V$MANAGED_STANDBY视图专用于显示物理Standby数据库相关进程的当前状态,该视图中的列也很有特点,查看进程状态时,通常我们会关注PROCESS ...