您的位置:首页 > 其它

关于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 的运行结果。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: