您的位置:首页 > 其它

多线程06_张孝祥-ThreadLocal类及应用技巧

2014-12-18 15:37 435 查看
使用ThreadLocal类实现线程范围内的共享数据:

确保每个线程都有自己私有的变量和取到自己的变量。下面用ThreadLocal类实现,替代上节课中的map用法

代码:

package org.yla.thread;

import java.util.Random;

/**
* 使用ThreadLocal类实现线程范围内的私有数据
* 替代上节课map的作用
* @author huo_chai_gun
* 2014年12月18日下午3:25:35
*/
public class ThreadLocalTest {

private static ThreadLocal<Integer> threadLocal = new ThreadLocal<Integer>();
public static void main(String[] args) {

//启动两个线程
for (int i = 0; i < 2; i++) {
new Thread(new Runnable() {
@Override
public void run() {
//创建每个线程私有的变量
int data = new Random().nextInt(100);
System.out.println(Thread.currentThread().getName()+" has put data: "+data);
//往local里面设置值
threadLocal.set(data);
new A().get();
new B().get();
}
}).start();
}
}

static class A{
public void get(){
int data =threadLocal.get();
System.out.println("A from "+Thread.currentThread().getName()+" has get data: "+data);
}
}

static class B{
public void get(){
int data =threadLocal.get();
System.out.println("B from "+Thread.currentThread().getName()+" has get data: "+data);
}
}
}


运行结果:

Thread-0 has put data: 48
Thread-1 has put data: 95
A from Thread-1 has get data: 95
A from Thread-0 has get data: 48
B from Thread-0 has get data: 48
B from Thread-1 has get data: 95

假设我们有多个线程需要范围内的共享数据,那么我们的代码就得改成下面的形式了:思路是把 其他属性的值打包成一个类

package org.yla.thread;

import java.util.Random;

/**
* 使用ThreadLocal类实现线程范围内的私有数据
* 替代上节课map的作用
* @author huo_chai_gun
* 2014年12月18日下午3:25:35
*/
public class ThreadLocalTest {

private static ThreadLocal<Integer> threadLocal = new ThreadLocal<Integer>();
private static ThreadLocal<MyThreadLocalScopeDate> myLocalScopeData = new ThreadLocal<MyThreadLocalScopeDate>();
public static void main(String[] args) {

//启动两个线程
for (int i = 0; i < 2; i++) {
new Thread(new Runnable() {
@Override
public void run() {
//创建每个线程私有的变量
int data = new Random().nextInt(100);
System.out.println(Thread.currentThread().getName()+" has put data: "+data);
//往local里面设置值
threadLocal.set(data);
MyThreadLocalScopeDate scopeDate = new MyThreadLocalScopeDate();
scopeDate.setName("name "+data);
scopeDate.setAge(data);
myLocalScopeData.set(scopeDate);
new A().get();
new B().get();
}
}).start();
}
}

static class A{
public void get(){
int data =threadLocal.get();
System.out.println("A from "+Thread.currentThread().getName()+" has get data: "+data);
MyThreadLocalScopeDate scopeDate=myLocalScopeData.get();
System.out.println("A from "+Thread.currentThread().getName()+" has get MyThreadLocalScopeDate name: "+scopeDate.getName()+" , age: "+scopeDate.getAge());
}
}

static class B{
public void get(){
int data =threadLocal.get();
System.out.println("B from "+Thread.currentThread().getName()+" has get data: "+data);
MyThreadLocalScopeDate scopeDate=myLocalScopeData.get();
System.out.println("B from "+Thread.currentThread().getName()+" has get MyThreadLocalScopeDate name: "+scopeDate.getName()+" , age: "+scopeDate.getAge());
}
}
}

class MyThreadLocalScopeDate{
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;
}

}


运行结果:

Thread-0 has put data: 2
Thread-1 has put data: 94
A from Thread-1 has get data: 94
A from Thread-0 has get data: 2
A from Thread-1 has get MyThreadLocalScopeDate name: name 94 , age: 94
A from Thread-0 has get MyThreadLocalScopeDate name: name 2 , age: 2
B from Thread-1 has get data: 94
B from Thread-0 has get data: 2
B from Thread-1 has get MyThreadLocalScopeDate name: name 94 , age: 94
B from Thread-0 has get MyThreadLocalScopeDate name: name 2 , age: 2

上面的代码虽然实现了功能,但是代码实现是很垃圾,一个线程有一个实例,那么多个线程就有多个实例,所以我们还要对代码进行修改:

思路:利用单例模式 实现线程范围内的共享数据 这样子就永远只有一个对象 但是每个线程拿这个对象的时后我们让他显示互斥效果 这样子就节省了内容的消耗 并且外部调用的时候 还看不见ThreadLocal对这个对象进行了封装

真正开发中应该这么设计比较好【注意】

代码:

package org.yla.thread;

import java.util.Random;

/**
* 使用ThreadLocal类实现线程范围内的私有数据
* @author huo_chai_gun
* 2014年12月18日下午3:25:35
*/
public class ThreadLocalTest {

private static ThreadLocal<Integer> threadLocal = new ThreadLocal<Integer>();
public static void main(String[] args) {

//启动两个线程
for (int i = 0; i < 2; i++) {
new Thread(new Runnable() {
@Override
public void run() {
//创建每个线程私有的变量
int data = new Random().nextInt(100);
System.out.println(Thread.currentThread().getName()+" has put data: "+data);
//往local里面设置值
threadLocal.set(data);
//获取自己线程的MyThreadLocalScopeDate实例对象
MyThreadLocalScopeDate myData = MyThreadLocalScopeDate.getThreadInstance();
myData.setName("name"+data);
myData.setAge(data);
new A().get();
new B().get();
}
}).start();
}
}

static class A{
public void get(){
int data =threadLocal.get();
System.out.println("A from "+Thread.currentThread().getName()+" has get data: "+data);
MyThreadLocalScopeDate myData = MyThreadLocalScopeDate.getThreadInstance();
System.out.println("A from "+Thread.currentThread().getName()+" has get MyThreadLocalScopeDate name: "+myData.getName()+" , age: "+myData.getAge());
}
}

static class B{
public void get(){
int data =threadLocal.get();
System.out.println("B from "+Thread.currentThread().getName()+" has get data: "+data);
MyThreadLocalScopeDate myData = MyThreadLocalScopeDate.getThreadInstance();
System.out.println("B from "+Thread.currentThread().getName()+" has get MyThreadLocalScopeDate name: "+myData.getName()+" , age: "+myData.getAge());
}
}
}

class MyThreadLocalScopeDate{//单例模式

private MyThreadLocalScopeDate(){};//构造方法私有化
private static ThreadLocal<MyThreadLocalScopeDate> map = new ThreadLocal<MyThreadLocalScopeDate>();//封装MyThreadLocalScopeDate是线程实现范围内共享

//思考AB两个线程过来的情况 自己分析 AB都需要的自己的对象 没有关系 所以不需要同步 如果有关系就需要同步了
public static /*synchronized*/MyThreadLocalScopeDate getThreadInstance(){
MyThreadLocalScopeDate instance =map.get();
if(instance==null){
instance = new MyThreadLocalScopeDate();
map.set(instance);
}
return instance;
}

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;
}

}


运行结果:

Thread-0 has put data: 24
Thread-1 has put data: 13
A from Thread-1 has get data: 13
A from Thread-1 has get MyThreadLocalScopeDate name: name13 , age: 13
A fr
4000
om Thread-0 has get data: 24
A from Thread-0 has get MyThreadLocalScopeDate name: name24 , age: 24
B from Thread-1 has get data: 13
B from Thread-1 has get MyThreadLocalScopeDate name: name13 , age: 13
B from Thread-0 has get data: 24
B from Thread-0 has get MyThreadLocalScopeDate name: name24 , age: 24
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  多线程 线程 thread