关于ThreadLocal的初步理解
来源:互联网 发布:明朝朝鲜知乎 编辑:程序博客网 时间:2024/04/30 10:03
package com.joker.threads.demo.thread.mainsub;
import java.util.HashMap;
import java.util.Random;
/**
*
* @author 线程范围内的数据共享如果不加map,则大家公用一个数据,而加入map,则避免这个情况出现
* 1最原始的写法,用hashMap
* 2用ThreadLocal
* ,ThreadLocal本身在存取的时候,使用的就是当前线程来存取的。一个ThreadLocal只能存储一个变量,
* 而如果需要共享多个变量,那么可以自定义一个变量来存储对个变量,比如USER下可以放age,name......
*
*/
public class ThreadLocalDemo {
public static int count;
public static HashMap<String, Integer> data = new HashMap<String, Integer>();
public static ThreadLocal<Integer> local = new ThreadLocal<Integer>();
/**
*
* 用hashMap实现的线程范围的数据共享
*/
public static void changeCountByMap(int c) {
String threadName = Thread.currentThread().getName();
int d = 0;
if (null == data.get(threadName)) {
d = c;
} else {
d = data.get(threadName) + c;
}
data.put(threadName, d);
System.out.println(Thread.currentThread().getName() + "addCount:"
+ data.get(Thread.currentThread().getName()));
}
public static void changCountByThreadLocal(int c) {
String threadName = Thread.currentThread().getName();
int d = 0;
if (null == local.get()) {
d = c;
} else {
d = local.get() + c;
}
local.set(d);
System.out.println(Thread.currentThread().getName()
+ "afterChangeCount:" + local.get());
}
public static void changeUser(final String name,final int age) {
System.out.println(Thread.currentThread().getName()+":进行shoWUser操作");
User.getInstance().setName(name);
User.getInstance().setAge(age);
}
public static void shoWUser() {
System.out.println(Thread.currentThread().getName()+":进行shoWUser操作:NAME:"+User.getInstance().getName());
System.out.println(Thread.currentThread().getName()+":进行shoWUser操作:AGE:"+User.getInstance().getAge());
}
public static void main(String[] args) {
/**
* 测试MAP和ThreadLocal对单一属性的用法
* 10条线程,每条线程结果过永远等于0,而不会互相影响。
*/
for (int i = 0; i < 10; i++) {
new Thread() {
@Override
public void run() {
int c = new Random().nextInt(100);
// changeCountByMap(c);
// changeCountByMap(-c);
changCountByThreadLocal(c);
changCountByThreadLocal(-c);
}
}.start();
}
/**
* 测试对封装对象的ThreadLocal
*
*/
// new Thread() {
// @Override
// public void run() {
// System.out.println(Thread.currentThread().getName()+"开始启动");
// changeUser("123", 1);
// shoWUser();
// }
// }.start();
// new Thread() {
// @Override
// public void run() {
// System.out.println(Thread.currentThread().getName()+"开始启动");
// changeUser("456", 2);
// shoWUser();
// }
// }.start();
}
}
/**
*
* 将ThreadlLocal放在user类中,而外部调用的时候只需要调用getInstance方法,
* 类似于单例,外部不需要考虑线程数据共享的问题,获得的都是只属于本线程的单例
*/
class User {
private static ThreadLocal<User> local = new ThreadLocal<User>();
public static User getInstance(){
User user = local.get();
if(null==user){
user = new User();
local.set(user);
}
return user;
}
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
import java.util.HashMap;
import java.util.Random;
/**
*
* @author 线程范围内的数据共享如果不加map,则大家公用一个数据,而加入map,则避免这个情况出现
* 1最原始的写法,用hashMap
* 2用ThreadLocal
* ,ThreadLocal本身在存取的时候,使用的就是当前线程来存取的。一个ThreadLocal只能存储一个变量,
* 而如果需要共享多个变量,那么可以自定义一个变量来存储对个变量,比如USER下可以放age,name......
*
*/
public class ThreadLocalDemo {
public static int count;
public static HashMap<String, Integer> data = new HashMap<String, Integer>();
public static ThreadLocal<Integer> local = new ThreadLocal<Integer>();
/**
*
* 用hashMap实现的线程范围的数据共享
*/
public static void changeCountByMap(int c) {
String threadName = Thread.currentThread().getName();
int d = 0;
if (null == data.get(threadName)) {
d = c;
} else {
d = data.get(threadName) + c;
}
data.put(threadName, d);
System.out.println(Thread.currentThread().getName() + "addCount:"
+ data.get(Thread.currentThread().getName()));
}
public static void changCountByThreadLocal(int c) {
String threadName = Thread.currentThread().getName();
int d = 0;
if (null == local.get()) {
d = c;
} else {
d = local.get() + c;
}
local.set(d);
System.out.println(Thread.currentThread().getName()
+ "afterChangeCount:" + local.get());
}
public static void changeUser(final String name,final int age) {
System.out.println(Thread.currentThread().getName()+":进行shoWUser操作");
User.getInstance().setName(name);
User.getInstance().setAge(age);
}
public static void shoWUser() {
System.out.println(Thread.currentThread().getName()+":进行shoWUser操作:NAME:"+User.getInstance().getName());
System.out.println(Thread.currentThread().getName()+":进行shoWUser操作:AGE:"+User.getInstance().getAge());
}
public static void main(String[] args) {
/**
* 测试MAP和ThreadLocal对单一属性的用法
* 10条线程,每条线程结果过永远等于0,而不会互相影响。
*/
for (int i = 0; i < 10; i++) {
new Thread() {
@Override
public void run() {
int c = new Random().nextInt(100);
// changeCountByMap(c);
// changeCountByMap(-c);
changCountByThreadLocal(c);
changCountByThreadLocal(-c);
}
}.start();
}
/**
* 测试对封装对象的ThreadLocal
*
*/
// new Thread() {
// @Override
// public void run() {
// System.out.println(Thread.currentThread().getName()+"开始启动");
// changeUser("123", 1);
// shoWUser();
// }
// }.start();
// new Thread() {
// @Override
// public void run() {
// System.out.println(Thread.currentThread().getName()+"开始启动");
// changeUser("456", 2);
// shoWUser();
// }
// }.start();
}
}
/**
*
* 将ThreadlLocal放在user类中,而外部调用的时候只需要调用getInstance方法,
* 类似于单例,外部不需要考虑线程数据共享的问题,获得的都是只属于本线程的单例
*/
class User {
private static ThreadLocal<User> local = new ThreadLocal<User>();
public static User getInstance(){
User user = local.get();
if(null==user){
user = new User();
local.set(user);
}
return user;
}
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
初步感觉ThreadLocal就是对每个线程都存储的Map,每个线程单独只操作的只属于该线程的资源。
测试MAP和ThreadLocal对单一属性的用法:运行截图如下:
Thread-0afterChangeCount:27
Thread-5afterChangeCount:96
Thread-5afterChangeCount:0
Thread-3afterChangeCount:6
Thread-3afterChangeCount:0
Thread-1afterChangeCount:46
Thread-1afterChangeCount:0
Thread-0afterChangeCount:0
Thread-7afterChangeCount:92
Thread-2afterChangeCount:35
Thread-7afterChangeCount:0
Thread-2afterChangeCount:0
Thread-9afterChangeCount:7
Thread-9afterChangeCount:0
Thread-8afterChangeCount:23
Thread-4afterChangeCount:47
Thread-6afterChangeCount:13
Thread-6afterChangeCount:0
Thread-4afterChangeCount:0
Thread-8afterChangeCount:0
如Thread0 的运行结果。
0 0
- 关于ThreadLocal的初步理解
- 对ThreadLocal的初步理解
- 关于ThreadLocal的理解
- 关于ThreadLocal的理解
- 关于ThreadLocal的理解
- 关于ThreadLocal的理解
- 关于threadlocal的理解
- 关于ThreadLocal的一点理解
- 关于ThreadLocal类的理解
- 关于ThreadLocal的一点理解
- 关于递归的初步理解
- 关于ViewPager的初步理解
- 关于ThreadLocal引起内存泄漏的理解
- 关于NP问题的初步理解
- 关于bag of words 的初步理解
- 关于版本管理的一些初步理解
- Java关于多态的初步理解
- 关于协程的初步理解
- 对iOS中block的一点领悟
- 实习面试总结
- Fixed - working copy lock by svn
- Oracle中替换like的方法
- 创建的web窗体中,添加的app_code文件夹不能调用的解决方法
- 关于ThreadLocal的初步理解
- Linux 上虚拟网络与真实网络的映射
- 首先启动哪个Activity
- 二叉树创建、遍历的递归和非递归实现
- 用OpenCV叠加(融合)两幅图像
- ASP.NET---Web Pages学习
- 第五周——分数类的雏形
- Opentext Cordys REST Gateway用户向导
- 告别程序员生涯,一点感慨,与诸君共勉(转CSDN)