最近在看ThreadLocal,看到WeakReference,学习一下
ExecutorService executorService = Executors.newCachedThreadPool();
Student student = new Student();
WeakReference<Student> weakReference = new WeakReference<>(student);
executorService.execute(() -> {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.gc();
});
executorService.execute(() -> {
while (weakReference.get() != null){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(System.currentTimeMillis()/1000);
}
});
//①
executorService.shutdown();
输出
1544711490
1544711491
1544711492
嗯,意料之中!于是又继续测试,在上文①处添加:
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
输出:
1544712033
1544712034
1544712035
1544712036
1544712037
1544712038
1544712039
1544712040
1544712041
...
这不科学啊,我只是sleep了3秒,并没有引用student,为什么没有回收?
我认为student是局部变量,当前方法持有引用student至方法结束,刚好和System.gc()所在的线程sleep时间一样,student应仍被引用。我尝试将main线程sleep 3秒改为sleep 2999ms,此时如果main结束了,则不再持有引用student,结果同第一种情况。