public class WeakReferenceTest {
/*
* 测试WeakReference,WeakReference引用的对象并没有被其他对象直接应用
*/
private static void testWeakReferenceNoDirectReference() throws Exception{
Object obj=new Object();
WeakReference<Object> weakRef=new WeakReference<>(obj);
System.out.println(weakRef.get());
obj=null;
System.gc();
Thread.sleep(3000);
System.out.println(weakRef.get());
}
public static void main(String[] args) {
try {
testWeakReferenceNoDirectReference();
} catch (Exception e) {
e.printStackTrace();
}
}
}
结果:
java.lang.Object@15db9742
null
public class WeakReferenceTest {
/*
* 测试WeakReference,WeakReference引用的对象有被其他对象直接应用
*/
private static void testWeakReferenceNoDirectReference() throws Exception{
Object obj=new Object();
WeakReference<Object> weakRef=new WeakReference<>(obj);
System.out.println(weakRef.get());
List<Object> objectList=new ArrayList();
objectList.add(obj);
obj=null;
System.gc();
Thread.sleep(3000);
System.out.println(weakRef.get());
}
public static void main(String[] args) {
try {
testWeakReferenceNoDirectReference();
} catch (Exception e) {
e.printStackTrace();
}
}
}
结果:
java.lang.Object@15db9742
java.lang.Object@15db9742
ThreadLocals是依附在Thread对象的一个成员变量,ThreadLocals对应的类是ThreadLocal里的ThreadLocalMap,ThreadLocalMap与我们常用的HashMap类似,它是由Entry组成的table数组(private Entry[] table;),这个数组Entry的key就是WeakReference,value就是ThreadLocal的一个对象
每个线程对象都有自己的threadLocals,他们的threadLocals值是不会相互干扰的,这也是ThreadLocal能获得自己的一个成员变量,去拿到自己的值,而不会交错、混淆拿到其他线程的值,这也是ThreadLocal在线程高并发提供一个好的方案
public class UserSessionContext {
private static ThreadLocal<UserSessionContext> threadLocal=ThreadLocal.withInitial(UserSessionContext::new);
public static UserSessionContext getUserSessionContext(){
return threadLocal.get();
}
public static void removeContext(){
threadLocal.remove();
}
private Long userId;
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
System.out.println(Thread.currentThread().getName()+"set userId="+userId);
this.userId = userId;
}
}
public class HTTPTest {
public static void main(String[] args) {
/*
* 模拟场景:HTTP服务端使用多线程处理来自不同用户的请求
*/
sampleTest();
}
private static void sampleTest() {
ExecutorService executorService = Executors.newFixedThreadPool(2);
executorService.submit(new Runnable() {
public void run() {
Long userId = 10000L;
doUseRequest(userId);
}
});
executorService.submit(new Runnable() {
public void run() {
Long userId = 20000L;
doUseRequest(userId);
}
});
}
private static void doUseRequest(Long userId){
UserSessionContext.getUserSessionContext().setUserId(userId);
String info = getMyInfo();
List<String> courses = getMyCourses();
System.out.println(Thread.currentThread().getName()+"info="+info+";courses="+JSONObject.toJSONString(courses));
UserSessionContext.removeContext();
}
private static String getMyInfo (){
return UserSessionContext.getUserSessionContext().getUserId()+"的个人信息";
}
private static List<String> getMyCourses (){
return Collections.singletonList(UserSessionContext.getUserSessionContext().getUserId()+"的java并发基础课程");
}
}