[Java] CountDownLatch和ExecutorService的简单使用

[Java] CountDownLatch和ExecutorService的简单使用

一、前言

  • 环境说明:

JDK:1.8

官方API文档:https://docs.oracle.com/javase/8/docs/api/index.html

参考:

https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CountDownLatch.html

https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html

二、记录

场景说明:

1.模拟多个动物,同时喂食,并记录过程

  • 动物接口
package com.demo.thread;

/**
 * 动物接口
 * */
public interface IAnimal {

    /**
     * 喂食
     * */
    public String feeding() throws InterruptedException;

}
  • 动物类:狗
package com.demo.thread;

/**
 * 狗
 * */
public class Dog implements IAnimal {
    @Override
    public String feeding() throws InterruptedException {
        Thread.sleep(3000); // 模拟耗时
        StringBuffer stringBuffer = new StringBuffer();
        stringBuffer.append("准备美味的骨头");
        stringBuffer.append(" > 开始喂食");
        return stringBuffer.toString();
    }
}
  • 动物类:猫
package com.demo.thread;

/**
 * 猫
 * */
public class Cat implements IAnimal {
    @Override
    public String feeding() throws InterruptedException {
        Thread.sleep(5000); // 模拟耗时
        StringBuffer stringBuffer = new StringBuffer();
        stringBuffer.append("准备美味的小鱼");
        stringBuffer.append(" > 开始喂食");
        return stringBuffer.toString();
    }
}
  • 任务类:喂食
package com.demo.thread;

import java.util.Map;
import java.util.concurrent.CountDownLatch;

/**
 * 任务类
 * */
public class FeedingTask implements Runnable {

    private String id;
    private IAnimal iAnimal;
    private CountDownLatch countDownLatch;
    private Map<String, String> map; // 结果

    // constructor
    public FeedingTask(String id, IAnimal iAnimal
                       , CountDownLatch countDownLatch, Map<String, String> map){
        this.id = id;
        this.iAnimal = iAnimal;
        this.countDownLatch = countDownLatch;
        this.map = map;
    }

    @Override
    public void run() {
        try {
            long start = System.currentTimeMillis(); // 开始时间戳

            String flow = iAnimal.feeding(); // 开始喂食
            map.put(id, flow); // 记录过程

            long end = System.currentTimeMillis(); // 结束时间戳
            System.out.println(id + " exec="+ (end - start) +"ms");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            countDownLatch.countDown(); // 计数器递减
        }
    }
}
  • 主入口
package com.demo.thread;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class MainDemo {

    public static void main(String[] args) throws InterruptedException {
        Map<String, String> map = new HashMap<>();
        CountDownLatch countDownLatch = new CountDownLatch(2); // M 个喂食任务
        ExecutorService executorService 
            = Executors.newFixedThreadPool(2); // N 个任务同时执行(线程池)
        // Dog Feeding
        executorService.execute(new FeedingTask("DOG", new Dog()
                                                , countDownLatch, map));
        // Cat Feeding
        executorService.execute(new FeedingTask("CAT", new Cat()
                                                , countDownLatch, map));

        // 等待所有动物喂食完成(等待计数器归零)
        countDownLatch.await();
        executorService.shutdown(); // 关闭执行线程池

        // 输出结果
        System.out.println(map.toString());
    }
}
  • 输出结果
DOG exec=3000ms
CAT exec=5000ms
{CAT=准备美味的小鱼 > 开始喂食, DOG=准备美味的骨头 > 开始喂食}

版权声明:本文为u011424614原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。