前段时间做毕设的时候想实现一个多图上传的功能,具体实现的时候本来是想实现多图异步同时上传的,但是需要知道最后一张图片上传成功的时间戳以及每张图片的上传情况(成功还是失败),有想过用轮寻来实现,但是感觉这样做并不优雅,最后只能暂时通过同步上传的方式实现。
最近在看公司项目代码时了解到了一个类CountDownLatch,在初步了解了这个类的功能后发现这个类可以用于辅助实现多图异步上传的功能,该类有几个比较重要的方法:
//构造方法
public CountDownLatch(int count)
// 调用此方法的线程会被阻塞,直到 CountDownLatch 的 count 为 0
public void await() throws InterruptedException 
// 和上面的 await() 作用基本一致,只是可以设置一个最长等待时间
public boolean await(long timeout, TimeUnit unit) throws InterruptedException
// 会将 count 减 1,直至为 0
public void countDown() 
通过这几个方法,写了一个小demo模拟多图上传,实现了最后一张图上传完成后再执行结果的回调等操作:
public class Test {
    public static void main(String[] args) {
        Random random = new Random(System.currentTimeMillis());
        CountDownLatch latch = new CountDownLatch(3);
        long start = System.currentTimeMillis();
        System.out.println("start at " + start);
        new UploadThread("img1", latch).random(random).start();
        new UploadThread("img2", latch).random(random).start();
        new UploadThread("img3", latch).random(random).start();
        try {
            latch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        long end = System.currentTimeMillis();
        System.out.println(String.format("end at %d , totally used %d ms", end, end - start));
    }
    static class UploadThread extends Thread {
        private final String name;
        private long timeMills;
        private final CountDownLatch latch;
        public UploadThread(String name, CountDownLatch latch) {
            this.name = name;
            this.latch = latch;
        }
        //随机生成一个时间戳,模拟上传图片所用的耗时
        public UploadThread random(Random random) {
            this.timeMills = random.nextInt(10_000);
            System.out.println(String.format("%s#%d create", name, timeMills));
            return this;
        }
        @Override
        public void run() {
            try {
                Thread.sleep(timeMills);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            super.run();
            latch.countDown();
            System.out.println(String.format("%s#%d - finished at %d", name, timeMills, System.currentTimeMillis()));
        }
    }
}
输出结果:
输出结果
Demo使用CountDownLatch解决了结束时间的问题,但是没有解决每个上传行为的结果分析,不过核心问题已经解决,上传状态可以封装一个UploadManager来保存记录每个上传行为的结果或状态,想法是这样的具体实现起来应该还是会有一些问题需要解决,这个就具体问题具体分析了。
时间关系,记录的比较潦草,希望后面能有时间再补一下CountDownLatch的一些细节性的知识,有空也尝试实现一下异步多图上传的功能。 = =















网友评论