目录

裴先生
裴先生
发布于 2020-10-01 / 4 阅读
0
0

Java 8 异步编程与时间处理实战指南

原创

异步API

以前我们用 Thread 或者 Runnable 来实现异步,这是Oracle官方做法,不过缺点很明显:对于复杂业务场景需要配置线程池,代码繁杂;对于新手容易造成不必要的Bug;如果涉及到线程锁或线程通讯就棘手了。

现在,Java 8 为我们提供了 CompletableFuture 类,可以完全解决以上问题。

runAsync() 异步无参返回

@Test
public void asyncThread() throws Exception {
    CompletableFuture async1 = CompletableFuture.runAsync(() -> {
        try {
            Thread.sleep(1000);
            System.out.println(Thread.currentThread().getName());
            System.out.println("none return Async");
        } catch (Exception e) {
            e.printStackTrace();
        }
    });
    // 调用get()将等待异步逻辑处理完成
    async1.get();
}

supplyAsync() 异步有参返回

@Test
public void asyncThread2() throws Exception {
    CompletableFuture<String> async2 = CompletableFuture.supplyAsync(() -> {
        return "hello";
    });
    String result = async2.get();
    // String result2 = async2.get(5L, TimeUnit.SECONDS);
    System.out.println(result);
}

allOf() 多个异步处理(针对有参返回)

@Test
public void asyncThread3() throws Exception {
    CompletableFuture<String> a = CompletableFuture.supplyAsync(() -> "hello");
    CompletableFuture<String> b = CompletableFuture.supplyAsync(() -> "youth");
    CompletableFuture<String> c = CompletableFuture.supplyAsync(() -> "!");

    CompletableFuture all = CompletableFuture.allOf(a, b, c);
    all.get();

    String result = Stream.of(a, b, c)
            .map(CompletableFuture::join)
            .collect(Collectors.joining(" "));

    System.out.println(result);
}

anyOf() 多个异步随机处理(针对有参返回)

@Test
public void asyncThread4() throws Exception {
    CompletableFuture<String> a = CompletableFuture.supplyAsync(() -> {
        try {
            Thread.sleep(20);
            return "hello";
        } catch (Exception e) {
            e.printStackTrace();
            return "none~";
        }
    });
    CompletableFuture<String> b = CompletableFuture.supplyAsync(() -> "youth");
    CompletableFuture<String> c = CompletableFuture.supplyAsync(() -> "!");

    CompletableFuture<Object> any = CompletableFuture.anyOf(a, b, c);
    String result = (String) any.get();

    System.out.println(result);
}

循环ForEach

for 循环不同的是,forEach 循环是建立在 Stream 之上的。而且比 foriterator 方便的是,它可以循环 Map 对象,如果您尝试配合 filter 处理就更赞了~

forEach对List的循环

@Test
public void listForeach() {
    List<String> lst = new ArrayList<String>(5) {{
        add("A");
        add("B");
        add("H");
        add("O");
        add("M");
    }};
    lst.forEach(System.out::println);
    lst.forEach((item) -> System.out.println(item.concat("_")));
}

forEach对数组的循环

@Test
public void arrForeach() {
    String[] strArr = new String[]{"A", "B", "C", "D"};

    Arrays.stream(strArr).forEach(System.out::println);
}

forEach对int范围的循环

@Test
public void numericForeach() {
    IntStream.range(0, 10).forEach(System.out::println);
}

forEach对Map的循环

@Test
public void mapForeach() {
    Map<String, Object> mps = new HashMap<String, Object>(5) {{
        put("a", 1);
        put("b", true);
        put("c", 23.44F);
        put("d", "hello");
        put("e", 11L);
    }};
    mps.forEach((k, v) -> System.out.println(k.concat(":").concat(String.valueOf(v))));
    String str = "hello";
}

时间类

Java 8 之前我们处理时间大多会涉及到这几个类:DateSimpleDateFormatCalendar。这种处理方式复杂、存在线程隐患、国际化困难、日期加减等处理麻烦等等。

现在有了 LocalDateLocalDateTimeDateTimeFormatter,生活就变得简单了。

常量定义

/**设置格式化模板**/
private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSS");
/**设置日期时区常量**/
public static final ZoneId CHINA_ZONE_ID = ZoneId.systemDefault();

Date转DateTime

/**Date格式化为DateTime**/
@Test
public void dateToDateTime() {
    Date date = new Date();
    LocalDateTime dateTime = date.toInstant().atZone(CHINA_ZONE_ID).toLocalDateTime();
    System.out.println(dateTime);
}

LocalDate/LocalDateTime转Date

/**LocalDate/LocalDateTime转Date**/
@Test
public void toDate() {
    // LocalDate
    LocalDate localDate = LocalDate.now();
    Date d1 = Date.from(localDate.atStartOfDay(CHINA_ZONE_ID).toInstant());
    System.out.println(d1);

    // LocalDateTime
    LocalDateTime localDateTime = LocalDateTime.now();
    Date d2 = Date.from(localDateTime.atZone(CHINA_ZONE_ID).toInstant());
    System.out.println(d2);
}

日期格式化

/**日期格式化**/
@Test
public void formatDate() {
    System.out.println(LocalDateTime.now().format(DATE_TIME_FORMATTER));
}

日期加减

/**日期加减**/
@Test
public void plusDay() {
    LocalDateTime dateTime = LocalDateTime.now(CHINA_ZONE_ID);
    //天
    dateTime = dateTime.plusDays(1);
    //时
    dateTime = dateTime.plusHours(-1);
    //分钟
    dateTime = dateTime.plusMinutes(30);
    System.out.println(dateTime.format(DATE_TIME_FORMATTER));
}

日期时间间隔

/**日期时间间隔**/
@Test
public void betweenDay() {
    // LocalDateTime
    LocalDateTime startDate = LocalDateTime.of(2019, 07, 01, 12, 12, 22);
    LocalDateTime endDate = LocalDateTime.of(2019, 07, 03, 12, 12, 22);
    Long withSecond = endDate.atZone(CHINA_ZONE_ID).toEpochSecond() - startDate.atZone(CHINA_ZONE_ID).toEpochSecond();
    System.out.println(withSecond / 60 / 60 / 24);

    // LocalDate
    LocalDate startDate2 = LocalDate.of(2019, 07, 01);
    LocalDate endDate2 = LocalDate.of(2019, 07, 03);
    Long withSecond2 = endDate2.toEpochDay() - startDate2.toEpochDay();
    System.out.println(withSecond2);
}

第一天和最后一天

/**第一天and最后一天**/
@Test
public void theLastDay() {
    // 当月第一天
    LocalDateTime dateTime = LocalDateTime.of(2019, 07, 03, 12, 12, 22);
    dateTime = dateTime.with(TemporalAdjusters.firstDayOfMonth());
    System.out.println(dateTime);
    
    // 当月最后一天
    dateTime = dateTime.with(TemporalAdjusters.lastDayOfMonth());
    System.out.println(dateTime);

    //当月的第几天
    dateTime = LocalDateTime.now();
    int dayOfMonth = dateTime.getDayOfMonth();
    System.out.println(dayOfMonth);
    
    // 当前周的第几天
    int dayOfWeek = dateTime.getDayOfWeek().getValue();
    System.out.println(dayOfWeek);
}

原创

版权声明:本博客原创文章,由 裴先生 2020年10月01日 发表。
转载说明:除特殊说明外本站文章皆由 CC BY-NC-SA 4.0 协议发布,转载须注明出处。


评论