利用高阶函数封装 CountDownLatch 多线程并发远程下载

CMS 里面的文章,需要把正文的图片保存到本地。这需求正好适合 CountDownLatch 来解决,它内部提供了一个计数器,完成了一件事情就减去一,最终为零表示所有任务结束。当前我们的任务就是并发下载多张图片,起初的写法是这样的(出处),

import java.util.concurrent.CountDownLatch;

public class PicDownload {
	static class Service {
		private CountDownLatch latch;

		public Service(CountDownLatch latch) {
			this.latch = latch;
		}

		public void exec(String url) {
			try {
				System.out.println(Thread.currentThread().getName() + " 开始下载");
				NetUtil.download(url, "c:/temp"); // 下载图片
				System.out.println(Thread.currentThread().getName() + " 下载完成");
			} finally {
				latch.countDown();
			}
		}
	}

	static String[] arr = new String[] { 
			"https://bbsimage.res.meizu.com/forum/2019/01/23/153122zrz85kuvubbiibbs.jpg", 
			"http://531.yishu1000.com/201906/004/1.jpg",
			"http://531.yishu1000.com/201906/004/2.jpg",
			"http://531.yishu1000.com/201906/004/3.jpg" };

	public static void main(String[] args) throws InterruptedException {
		CountDownLatch latch = new CountDownLatch(arr.length);
		Service service = new Service(latch);

		for (String url : arr) 
			new Thread(() -> service.exec(url)).start();
		
		latch.await();
		System.out.println("全部完成");
	}
}

小小的代码工作良好,貌似没什么好说的。——但是窃以为,使用内部类而且特意构造器参数 CountDownLatch latch 不太优雅,于是改为函数式的,

import java.util.concurrent.CountDownLatch;
import java.util.function.BiFunction;

public class PicDownload {
	static BiFunction<String, CountDownLatch, Runnable> exec = (url, latch) -> {
		Runnable r = () -> {
			try {
				System.out.println(Thread.currentThread().getName() + "开始下载");
				NetUtil.download(url, "c:/temp");
				System.out.println(Thread.currentThread().getName() + " 下载完成");
			} finally {
				latch.countDown();
			}
		};

		return r;
	};

	static String[] arr = new String[] { 
			"https://bbsimage.res.meizu.com/forum/2019/01/23/153122zrz85kuvubbiibbs.jpg", 
			"http://531.yishu1000.com/201906/004/1.jpg", 
			"http://531.yishu1000.com/201906/004/2.jpg",
			"http://531.yishu1000.com/201906/004/3.jpg" };

	public static void main(String[] args) throws InterruptedException {
		CountDownLatch latch = new CountDownLatch(arr.length);

		for (String url : arr)
			new Thread(exec.apply(url, latch)).start();

		latch.await();
		System.out.println("全部完成");
	}
}
发布了293 篇原创文章 · 获赞 260 · 访问量 232万+

猜你喜欢

转载自blog.csdn.net/zhangxin09/article/details/90767875