构建高效且可伸缩的结果缓存引申的并发测试规范化

有些东西其实就是一层纸,当你偶然穿透的时候,就会豁然开朗,眼前一亮。
以前总是对一些并发测试不感冒,有时候觉得我从下手的感觉。但是不自己亲自测试一把又觉得不放心,于是总是在Thread里面来来回回的修改,
在run方法中做这个中修改,总是乱乱的感觉。今天突然从别人的代码中顿悟了,体系终于明朗了。
我以构建高效且可伸缩的结果缓存为例,希望给大家启示。
// 定义泛型计算接口
public interface Computable<A, W> {
W compute(A arg) throws InterruptedException;
}
// 实现一个具体类型的计算接口
public class ExpensiveFunction implements Computable<String, BigInteger> {
    public BigInteger compute(String arg) {
        for (int i = 0; i < 1000000000; i++);
        System.out.println(Thread.currentThread().getName() + "計算中......");
        return new BigInteger(arg);
    }
}

// 泛型计算接口具体实现
public class Memoizer<A, W> implements Computable<A, W> {
    private final ConcurrentHashMap<A, Future<W>> cache = new ConcurrentHashMap<A, Future<W>>();
    private final Computable<A, W> com;

    public Memoizer(Computable<A, W> c) {
        this.com = c;
    }

    @Override
    public W compute(final A arg) throws InterruptedException {
        Future<W> f = cache.get(arg);
        if (f == null) {
            Callable<W> eval = new Callable<W>() {
                @Override
                public W call() throws Exception {
                    return com.compute(arg);
                }
            };
            FutureTask<W> ft = new FutureTask<W>(eval);
            f = cache.putIfAbsent(arg, ft);
            if (f == null) {
                f = ft;
                ft.run();
            }
        }
        try {
            return f.get();
        } catch (ExecutionException e) {
            // TODO Auto-generated catch block
            throw new InterruptedException();
        }
    }
}

// 说了这么多,其实并发测试才是关键,条理的实现,优雅明了
// 在相应的开发中,往往演变为util类
public class ComputeClient {
    private static ExpensiveFunction ef = new ExpensiveFunction();
    private static final Memoizer<String, BigInteger> memoizer = new Memoizer<String, BigInteger>(ef);
    public static BigInteger compute(String arg) throws InterruptedException {
        return memoizer.compute(arg);
    }
}
// 模拟一个线程,你可以是servlet,action,调用开始
public class CacheThread extends Thread {
    private String arg;

    public MyCacheThread(String arg) {
        this.arg = arg;
    }

    public void run() {
        try {
            System.out.println(ComputeClient.compute(arg));
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

// 大规模并发开始,走起来,小伙伴们。
// 如果想要同时大规模启动线程,参照我以前的关于闭锁来实现并发测试
public class CacheDemo {

    /**
     * @param args
     */
    public static void main(String[] args) {
        for (int i = 0; i < 5; i++) {
            if (i == 0 || i == 1) {
                new CacheThread(String.valueOf(i + 2)).start();
            } else {
                new CacheThread(String.valueOf(i)).start();
            }
        }
    }
}
纸上得来终觉浅,绝知此事要躬行。学习,coding,test,一步步走向体系,加油!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值