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("全部完成");
}
}