这一章节我们来讨论一下对象逸出的其他解决方案。
1.由于出现对象逸出都是在多线程环境下,那么,我们换成单线程即可,当然,这个方法基本没有人使用, 因为现在都是多核处理器,为了提升性能,不可能使用单核,但是下面我也给出例子吧。
package com.ray.deepintothread.ch04.topic_2;
public class Ad_hoc {
private int id = 0;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public void addId() {
id++;
}
public static void main(String[] args) {
Ad_hoc ad_hoc = new Ad_hoc();
for (int i = 0; i < 10; i++) {
ad_hoc.addId();
System.out.println(ad_hoc.getId());
}
for (int i = 0; i < 10; i++) {
ad_hoc.setId(i);
System.out.println(ad_hoc.getId());
}
}
}
2.栈封闭
其实就是把全局变量变成局部变量,在多线程环境下,只能够在独立线程里面访问或引用
package com.ray.deepintothread.ch04.topic_2;
import java.util.HashSet;
public class CloseStack extends Thread{
public static void test() {
HashSet<String> set = new HashSet<>();
for (int i = 0; i < 10; i++) {
set.add(i + "");
}
}
@Override
public void run() {
test();
}
public static void main(String[] args) {
new CloseStack().start();
new CloseStack().start();
new CloseStack().start();
}
}
3.使用ThreadLocal
ThreadLocal把相应的属性域赋值一份,线程读写的都只是属性域的副本。
package com.ray.deepintothread.ch04.topic_2;
public class ThreadLocalTest extends Thread {
private int count = 0;
public ThreadLocal<Integer> intThreadLocal = new ThreadLocal<Integer>() {
protected Integer initialValue() {
return count;
};
};
public int getCount() {
return intThreadLocal.get();
}
public void addCount() {
intThreadLocal.set(count++);
}
@Override
public void run() {
try {
for (int i = 0; i < 3; i++) {
addCount();
System.out.println("Thread[" + getName() + "] count[" + getCount() + "]");
sleep(50);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws InterruptedException {
new ThreadLocalTest().start();
Thread.sleep(100);
new ThreadLocalTest().start();
Thread.sleep(100);
new ThreadLocalTest().start();
}
}
输出:
Thread[Thread-0] count[0]
Thread[Thread-0] count[1]
Thread[Thread-1] count[0]
Thread[Thread-0] count[2]
Thread[Thread-1] count[1]
Thread[Thread-2] count[0]
Thread[Thread-1] count[2]
Thread[Thread-2] count[1]
Thread[Thread-2] count[2]
从输出可以看见,每一个线程都是单独读写工作内存里面的属性副本。
但是,这里会出现一个问题,如果这个属性域是每一个线程都需要更新状态的呢?这个时候必须同步,下面的章节会有想要的对比,这一章节就不展开。
总结:这一章节我们讨论了对象逸出的其他解决方案-主要是ThreadLocal的应用。
这一章节就到这里,谢谢
------------------------------------------------------------------------------------
我的github:https://github.com/raylee2015/DeepIntoThread
目录:http://blog.csdn.net/raylee2007/article/details/51204573