打造高性能缓存(四)使用ThreadLocal确认时间的统一性
最后更新于:2022-08-17 13:42:13
通过ThreadLocal的线程隔离特性,查看程序是否真的时同一个时间点触发的。以此来解决每个线程都有存储独立信息的需求
class ThreadSafeFormatter {
public static ThreadLocal dateFormatThreadLocal = new ThreadLocal() {
// 每个线程会调用本方法一次,用于初始化
@Override
protected Object initialValue() {
// 只查看分秒即可
return new SimpleDateFormat("mm:ss");
}
// 首次调用本方法时,会调用initialValue;后面的调用会返回第一次创建的值
@Override
public Object get() {
return super.get();
}
};
}
public class TestCache10 {
static TestCache7 expensiveComputer = new TestCache7<>(new ExpensiveFunction());
static CountDownLatch countDownLatch = new CountDownLatch(1);
public static void main(String[] args) throws InterruptedException {
ExecutorService service = Executors.newFixedThreadPool(100);
long startTime = System.currentTimeMillis();
for (int i = 0; i < 100; i++) {
service.submit(() -> {
Integer result = null;
try {
System.out.println(Thread.currentThread().getName() + "开始等待");
countDownLatch.await();
SimpleDateFormat simpleDateFormat = ThreadSafeFormatter.dateFormatThreadLocal.get();
String time = simpleDateFormat.format(new Date());
System.out.println(time+Thread.currentThread().getName() + "被放行");
result = expensiveComputer.computer("666");
System.out.println(result);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
});
}
Thread.sleep(3000l);
countDownLatch.countDown();
}
}
结果
pool-2-thread-3开始等待
pool-2-thread-4开始等待
pool-2-thread-1开始等待
...
27:54pool-2-thread-14被放行
27:54pool-2-thread-30被放行
从FutureTask调用了计算逻辑
27:54pool-2-thread-44被放行
27:54pool-2-thread-39被放行
27:54pool-2-thread-98被放行
...
666
666
...
666
666
从打印结果可以看出,所有的线程都是统一行动,所有时间不会超过1秒钟