java线程池延期执行一次_Java使用者的延期执行

java线程池延期执行一次

在前面的博客文章(“ 延迟执行Java的供应商 “),我引用礁HORSTMANN陈述书中‘ 的Java SE8为真的很急关于lambda表达式’,‘所有的lambda表达式的点被推迟执行 。’ Horstmann在最后一年Dobb博士的杂志写了一篇名为《 Java 8中的Lambda表达式 》的文章,其中他使用不同的术语写了类似的声明,“ Lambda表达式是可以传递的代码块,因此可以稍后执行一次或多次。”

该较早的文章中 ,我研究了JDK中的lambda表达式如何与标准功能接口Supplier配合使用,以在“仅在必要时提供”单个值且未传递任何参数的情况下支持延迟执行。 在本文中,我重点介绍JDK提供的示例,这些示例使用Consumer标准功能接口“仅在必要时”“使用”或“处理”特定代码块。 Supplier接受任何参数并仅返回一个响应,而Consumer接受一个或多个参数并且不返回响应。 在Supplier上调用的方法是get()方法,并且是Consumeraccept(T)方法。 根据定义, Consumer将“副作用”,因为它“消费”了提供的代码块。

java.util.function包中提供了许多Consumer样式的标准功能接口。 这些都不返回结果(这就是为什么他们是消费者!),但是它们在接受参数的数量和类型上有所不同(但是它们都至少接受一个参数)。 这些在这里列出:

本文的其余部分将研究Consumer和相关类的JDK使用的子集,以帮助演示它们如何以及何时有用。

偷看流元素流

在博客文章“ 使用Stream.peek窥视Java Streams内部 ”中,我讨论了可用于查看流中流动元素的中间操作 Stream.peek(Consumer) 。 这对于理解各种流操作对其各自的流元素所做的操作非常有用。 一种常见的实现方法是让提供给peek方法的Consumer是对System.out的调用。 println将当前处理的流元素打印到标准输出(或记录该元素或将其打印到标准错误)。 Javadoc文档中为Stream.peek(Consumer)方法提供了一个示例:

Stream.of("one", "two", "three", "four")
   .filter(e -> e.length() > 3)
   .peek(e -> System.out.println("Filtered value: " + e))
   .map(String::toUpperCase)
   .peek(e -> System.out.println("Mapped value: " + e))
   .collect(Collectors.toList());

由于println(-)方法的各种重载版本都接受一个参数,但不返回任何内容,因此它们完全符合“ Consumer”的概念。

在迭代流元素上指定操作

尽管Stream.peek(Consumer)是一个中间操作,但Stream提供了另外两个接受Consumer方法,它们都是终端操作 ,并且都是“针对每个”方法。 方法Stream.forEach(Consumer)是一种对流的元素以“显式不确定性”的方式执行所提供的Consumer指定的操作的方法。 如果该流具有遇到顺序,则Stream.forEachOrdered(Consumer)方法将以所提供的Consumer 按照流的“ 遇到顺序 ”执行指定的操作。 在这两种方法的情况下,基于Consumer的“动作”都应该是“ 无干扰的” 。 两种方法都在下面演示。

Set.of("one", "two", "three", "four")
   .stream()
   .forEach(i -> out.println(i.toUpperCase()));

Stream.of("one", "two", "three", "four")
   .forEach(i -> out.println(i.toUpperCase()));

List.of("one", "two", "three", "four")
   .stream()
   .forEachOrdered(i -> out.println(i.toUpperCase()));

Stream.of("one", "two", "three", "four")
   .forEachOrdered(i -> out.println(i.toUpperCase()));

上面的例子看起来非常相似。 当使用并行流处理时, forEach可能导致与forEachOrdered截然不同的结果的最明显情况是。 在这种情况下,它将使大多数发送者使用forEach而不是forEachOrdered

在可迭代元素上指定操作

前面的代码示例显示了使用Stream.forEach(Consumer)方法来迭代流。 这些示例还演示了如何通过首先在这些集合上调用stream()SetList进行此操作。 有方便的方法,但是,通过限定可迭代和执行由这些集合的实现,其接受一个Consumer ,并允许使用该集合的迭代forEach方法。 下一个代码清单中显示了此示例。

Set.of("one", "two", "three", "four")
   .forEach(i -> out.println(i.toUpperCase()));
List.of("one", "two", "three", "four")
   .forEach(i -> out.println(i.toUpperCase()));

尽管在上面的示例中使用了集合,但是实现Iterable的所有对象通常都将支持forEach方法(或违反接口的广告约定)。

指定映射条目迭代时的操作

尽管Java的Map接口没有像SetList那样扩展Iterable接口,但是Java Map仍然具有类似的功能,可以指定使用者“消费” Map每个条目。 因为Map有两个输入参数(键和值),所以它的forEach方法接受BiConsumer而不是到目前为止本文中讨论的Consumer 。 接下来显示一个简单的示例。

Map.of("Denver", "Colorado",
       "Cheyenne", "Wyoming",
       "Salt Lake City", "Utah",
       "Boise", "Idaho")
   .forEach((c, s) -> out.println(c + " is the capital of " + s));

走栈

StackWalkerJDK 9的一个受欢迎的补充,它提供了一种线程安全的方法来细读堆栈跟踪,并且是对StackTraceElement方法的重大改进。 对于开发人员来说,使用StackWalker.walk(Function)可能更常见,但是这篇文章是关于Consumer ,因此重点是StackWalker.forEach(Consumer) 。 此方法类似于先前讨论的Stream.forEachIterable.forEach方法,并在下一个代码清单中进行演示。

StackWalker.getInstance().forEach(out::println);

尽管JDK对ConsumerBiConsumer以及其他类型的标准Consumer样式功能接口有更多的JDK使用 ,但本文中我要介绍的最后一个示例来自Optional类。

仅在存在时应用

方法Optional.ifPresent(Consumer)Optional.ifPresentOrElse(Consumer)推迟执行提供的Consumer ,以便仅在Optional不是“空”(包含非null值)的情况下才调用提供的Consumer 。 这是一个简单但功能强大的概念,简单易懂的示例说明了它们是如何工作的。

public void demonstrateOptionalIfPresent()
{
   getMiddleName(true).ifPresent(n -> out.println("Middle Name: " + n));
}

public void demonstrateOptionalIfPresentOrElse()
{
   getMiddleName(false).ifPresentOrElse(
      n -> out.println("Middle Name: " + n),
      () -> displayMissingMiddleName());
}

private Optional<String> getMiddleName(final boolean present)
{
   return present ? Optional.of("Wayne") : Optional.empty();
}

private void displayMissingMiddleName()
{
   out.println("No middle name provided!");
}

如上面的代码清单所示,如果Optional不为空,则Optional.ifPresent和JDK 9引入的Optional.ifPresentOrElse()仅调用提供的Consumer 。 如果Optional为空,则ifPresent方法不执行任何操作,而ifPresentOrElse调用第二个参数( Runnable )。

接受一个或多个参数且不返回任何结果的标准Java功能接口包括一般的Consumer以及某些专门的使用者。 这些对于将执行推迟到给定条件发生之前(例如被迭代或确定存在)有用,并且在该条件发生时要应用的行为涉及一个或多个输入参数,而无需提供响应。 GitHub上提供了本文中显示的源代码示例。

翻译自: https://www.javacodegeeks.com/2018/06/deferred-execution-java-consumer.html

java线程池延期执行一次

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值