对性能有何帮助(读书笔记)
为每一个线程分配一个独立的对象对系统性能也许是有帮助的,当然了,这也不一定,这完全取决于共享对象的内部逻辑,如果共享对象对于竞争的处理容易引起性能损失,我们还是考虑使用ThreadLocal为每一个线程分配单独的对象.一个经典的案例就是在多线程下产生随机数:
public class RandomDemo { public static final int GET_COUNT = 10000000; public static final int THREAD_COUNT = 4; static ExecutorService exe = Executors.newFixedThreadPool(THREAD_COUNT); public static Random rnd = new Random(123); public static ThreadLocal<Random> tRnd = new ThreadLocal<Random>() { @Override protected Random initialValue() { return new Random(123); } }; public static class RndTask implements Callable<Long> { private int mode = 0; public RndTask(int mode) { this.mode = mode; } public Random getRondom() { if (mode == 0) { return rnd; } else if (mode == 1) { return tRnd.get(); } else { return null; } } /** * Computes a result, or throws an exception if unable to do so. * * @return computed result * @throws Exception if unable to compute a result */ @Override public Long call() throws Exception { long b = System.currentTimeMillis(); for (long i = 0; i < GET_COUNT; i++) { getRondom().nextInt(); } long e = System.currentTimeMillis(); System.out.println(Thread.currentThread().getName() + " spend " + (e - b) + "ms"); return e - b; } } public static void main(String[] args) throws ExecutionException, InterruptedException { Future<Long>[] futs = new Future[THREAD_COUNT]; for (int i = 0; i < THREAD_COUNT; i++) { futs[i] = exe.submit(new RndTask(0)); } long totaltime = 0; for (int i = 0; i < THREAD_COUNT; i++) { totaltime += futs[i].get(); } System.out.println("多线程访问同一个Random实例:" + totaltime + "ms"); for (int i = 0; i < THREAD_COUNT; i++) { futs[i] = exe.submit(new RndTask(1)); } totaltime = 0; for (int i = 0; i < THREAD_COUNT; i++) { totaltime += futs[i].get(); } System.out.println("使用ThreadLocal包装Random实例:" + totaltime + "ms"); exe.shutdown(); } }
上述代码运行结果,如下:
效果是很明显的,