关于ThreadLocal的初步理解
2014-03-26 13:43
330 查看
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;
}
}
初步感觉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 的运行结果。
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 的运行结果。
相关文章推荐
- 关于ThreadLocal的理解
- 关于用户态和内核态的初步理解
- 关于三元运算符的初步应用及理解
- 关于ThreadLocal引起内存泄漏的理解
- 关于ThreadLocal的一点理解
- javaweb学习笔记之关于分层结构的初步理解
- 关于单点登录【SSO】的初步理解
- 关于NP问题的初步理解
- 关于ThreadLocal的理解
- 关于JSP乱码问题的初步理解和解决
- 关于bag of words 的初步理解
- 关于面对抽象编程的一些初步理解
- 关于对多项式的两种表示法的初步理解
- 关于版本管理的一些初步理解
- 关于ThreadLocal的一点理解
- Java 关于ThreadLocal线程池的简单理解
- 关于ThreadLocal的理解
- 关于对象池的初步理解与使用
- rn笔记:关于navigator的初步理解
- 关于递归的初步理解