谁给个ThreadLocal的简单例子

aotian16 2011-09-28 02:34:34
该类提供了线程局部 (thread-local) 变量。这些变量不同于它们的普通对应物,因为访问某个变量(通过其 get 或 set 方法)的每个线程都有自己的局部变量,它独立于变量的初始化副本。ThreadLocal 实例通常是类中的 private static 字段,它们希望将状态与某一个线程(例如,用户 ID 或事务 ID)相关联。

看的不是很懂,
网上的例子也找不到
特来请教
给个小例子就行了
...全文
212 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
my_caterpillar 2011-09-28
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 aotian16 的回复:]

引用 3 楼 my_caterpillar 的回复:

楼主,给你写一个例子


在你的基础上写个个对比版
Java code
package threadlocaltest;

public class MyNumber {
private static ThreadLocal<Integer> number = new ThreadLocal<Integer>() {
……
[/Quote]

你这不对啊 这样的话 两个线程就可以随便修改同一个 数据了 已经完全危险了
aotian16 2011-09-28
  • 打赏
  • 举报
回复
知道了
initialValue()方法只调用一次
又修改了下,这样比较容易看了
package threadlocaltest;

public class Test1 {
public static void main(String[] args) {
Thread[] t = new Thread[3];
for (int i = 0; i < 3; i++) {
t[i] = new Thread() {
public void run() {
for (int i = 0; i < 3; i++) {
System.out.printf("%s, id=%d, count1=%d, times=%s\n",
getName(), SampleThreadLocal.getId(),
SampleThreadLocal.getCount1(), i);
}
}
};
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
t[i].start();
}
}
}

class SampleThreadLocal {
private static int count = 0;
private static int count1 = 0;
private static final ThreadLocal<Integer> id = new ThreadLocal<Integer>() {
protected Integer initialValue() {
return count++;
}
};

public static int getId() {
return id.get();
}

public static synchronized int getCount1() {
return count1++;
}
}


结果

Thread-0, id=0, count1=0, times=0
Thread-0, id=0, count1=1, times=1
Thread-0, id=0, count1=2, times=2
Thread-1, id=1, count1=3, times=0
Thread-1, id=1, count1=4, times=1
Thread-1, id=1, count1=5, times=2
Thread-2, id=2, count1=6, times=0
Thread-2, id=2, count1=7, times=1
Thread-2, id=2, count1=8, times=2
aotian16 2011-09-28
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 qybao 的回复:]

for example
Java code
public class Test {
public static void main(String[] args) {
Thread[] t = new Thread[3];
for (int i=0; i<3; i++) {
t[i] = new Thread() {
……
[/Quote]
看了你的, 修改了下,反而迷糊了
package threadlocaltest;

public class Test1 {
public static void main(String[] args) {
Thread[] t = new Thread[3];
for (int i = 0; i < 3; i++) {
t[i] = new Thread() {
public void run() {
for (int i = 0; i < 3; i++) {
System.out.printf("%s, id=%d, count1=%d, times=%s\n",
getName(), SampleThreadLocal.getId(),
SampleThreadLocal.getCount1(), i);
}
}
};
t[i].start();
}
}
}

class SampleThreadLocal {
private static int count = 0;
private static int count1 = 0;
private static final ThreadLocal<Integer> id = new ThreadLocal<Integer>() {
protected Integer initialValue() {
return count++;
}
};

public static int getId() {
return id.get();
}

public static int getCount1() {
return count1++;
}
}

结果怎么这样的

Thread-2, id=0, count1=0, times=0
Thread-0, id=1, count1=1, times=0
Thread-0, id=1, count1=3, times=1
Thread-0, id=1, count1=4, times=2
Thread-1, id=0, count1=0, times=0
Thread-1, id=0, count1=5, times=1
Thread-1, id=0, count1=6, times=2
Thread-2, id=0, count1=2, times=1
Thread-2, id=0, count1=7, times=2
aotian16 2011-09-28
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 my_caterpillar 的回复:]

楼主,给你写一个例子

[/Quote]
在你的基础上写个个对比版
package threadlocaltest;

public class MyNumber {
private static ThreadLocal<Integer> number = new ThreadLocal<Integer>() {
protected Integer initialValue() {
return 0;
}
};

public Integer getNext() {
number.set(number.get() + 1);
return number.get();
}

public static void main(String[] args) {
MyNumber mynumber = new MyNumber();

MyThread mt1 = new MyThread(mynumber);
MyThread mt2 = new MyThread(mynumber);

mt1.start();
mt2.start();
}
}

class MyThread extends Thread {
private MyNumber my_number;

public MyThread(MyNumber my_number) {
this.my_number = my_number;
}

public void run() {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName() + "-number:"
+ my_number.getNext());
}
}
}


package threadlocaltest;

public class MyNumber1 {
private static Integer number = 0;

public Integer getNext() {
number++;
return number;
}

public static void main(String[] args) {
MyNumber1 mynumber = new MyNumber1();

MyThread1 mt1 = new MyThread1(mynumber);
MyThread1 mt2 = new MyThread1(mynumber);

mt1.start();
mt2.start();
}
}

class MyThread1 extends Thread {
private MyNumber1 my_number;

public MyThread1(MyNumber1 my_number) {
this.my_number = my_number;
}

public void run() {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName() + "-number:"
+ my_number.getNext());
}
}
}
my_caterpillar 2011-09-28
  • 打赏
  • 举报
回复
注:ThreadLocal 和 synchronized 相比 前一个以空间取代时间,每个访问同一个变量的线程都拥有该变量的一个副本,后一个以时间代替空间 多个线程访问 会进行排队 拿到的是同一个变量

以上纯属个人理解
qybao 2011-09-28
  • 打赏
  • 举报
回复
for example
public class Test {
public static void main(String[] args) {
Thread[] t = new Thread[3];
for (int i=0; i<3; i++) {
t[i] = new Thread() {
public void run() {
for (int i=0; i<3; i++) {
System.out.printf("%s, id=%d, times=%s\n", getName(), SampleThreadLocal.getId(), i);
}
}
};
t[i].start();
}
}
}

class SampleThreadLocal {
private static int count = 0;
private static final ThreadLocal <Integer> id =
new ThreadLocal <Integer> () {
protected Integer initialValue() {
return count++;
}
};
public static int getId() {
return id.get();
}
}

LZ可以看看,每个线程不管取多少次id,都不会发生变化
my_caterpillar 2011-09-28
  • 打赏
  • 举报
回复
楼主,给你写一个例子
public class MyNumber {
//使用ThreadLocal 维护唯一的变量
private static ThreadLocal<Integer> number = new ThreadLocal<Integer>() {
//去看ThreadLcoal的源代码,重写initialVal()方法,否则返回null
protected Integer initialValue() {
return 0;
}
}

//拿到下一个号码
public Integer getNext() {
//ThreadLocal变量在调用set或者是get方法的时候,才回去调用initialValue() 且调用一次
number.set(number.get()+1);
return number.get();
}

public static void main(String[] args) {
MyNumber mynumber = new MyNumber();
//这里 传入的 mynumber 是同一个对象 但是打印的结果却是相互不影响
//因为ThreadLocal保证了每个访问该变量的线程都有一个独立的副本
MyThread mt1 = new MyThread(mynumber);
MyThread mt2 = new MyThread(mynumber);

mt1.start();
mt2.start();
}
}

class MyThread implements Runnable{
private MyNumber my_number;
public MyThread(MyNumber my_number) {
this.my_number = my_number;
}

public void run() {
for(int i=0;i<5;i++) {
syso(Thread.currentThread.getName+"-number:"+my_number.getNext());
}
}
}

//以上就是一个小例子,如果有什么不懂,可以留言给我
wtc860104 2011-09-28
  • 打赏
  • 举报
回复
你就当他是个map
而且每个线程都不共享的map
zl3450341 2011-09-28
  • 打赏
  • 举报
回复
这样吧。你用一个类 里面定义一个ThreadLocal 随便保存一点东西。
写2个线程,一个线程将ThreadLocal的值改变一样。
在另一个线程里面,你读取出来,你发现,线程1所做的修改仅影响到线程1,并没有影响到线程2ThreadLocal里面的值。

62,616

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧