java线程池延期执行一次_Java使用者的延期执行
java線程池延期執行一次
在前面的博客文章(“ 延遲執行Java的供應商 “),我引用礁HORSTMANN的陳述書中‘ 的Java SE8為真的很急關于lambda表達式’,‘所有的lambda表達式的點被推遲執行 。’ Horstmann在最后一年為Dobb博士的雜志寫了一篇名為《 Java 8中的Lambda表達式 》的文章,其中他使用不同的術語寫了類似的聲明,“ Lambda表達式是可以傳遞的代碼塊,因此可以稍后執行一次或多次。”
在該較早的文章中 ,我研究了JDK中的lambda表達式如何與標準功能接口Supplier配合使用,以在“僅在必要時提供”單個值且未傳遞任何參數的情況下支持延遲執行。 在本文中,我重點介紹JDK提供的示例,這些示例使用Consumer標準功能接口“僅在必要時”“使用”或“處理”特定代碼塊。 Supplier接受任何參數并僅返回一個響應,而Consumer接受一個或多個參數并且不返回響應。 在Supplier上調用的方法是get()方法,并且是Consumer的accept(T)方法。 根據定義, Consumer將“副作用”,因為它“消費”了提供的代碼塊。
java.util.function包中提供了許多Consumer樣式的標準功能接口。 這些都不返回結果(這就是為什么他們是消費者!),但是它們在接受參數的數量和類型上有所不同(但是它們都至少接受一個參數)。 這些在這里列出:
- 消費者 –接受單個論點的一般Consumer ,將成為本文大部分示例的關注中心。
- BiConsumer –接受兩個參數,而不是一個參數(“ 消費者的兩類專業化”)
- DoubleConsumer –適用于原始double的特殊消費者
- IntConsumer –原始int的專門消費者
- LongConsumer –適用于原始long的專業消費者
- ObjDoubleConsumer –接受兩個參數的專用消費者 ,第一個為Object類型,第二個為double類型
- ObjIntConsumer –接受兩個參數的專用消費者 ,第一個為Object類型,第二個為int類型
- ObjLongConsumer –接受兩個參數的專用消費者,第一個為Object類型,第二個為long類型
本文的其余部分將研究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()對Set和List進行此操作。 有方便的方法,但是,通過限定可迭代和執行由這些集合的實現,其接受一個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接口沒有像Set和List那樣擴展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));走棧
StackWalker是JDK 9的一個受歡迎的補充,它提供了一種線程安全的方法來細讀堆棧跟蹤,并且是對StackTraceElement方法的重大改進。 對于開發人員來說,使用StackWalker.walk(Function)可能更常見,但是這篇文章是關于Consumer ,因此重點是StackWalker.forEach(Consumer) 。 此方法類似于先前討論的Stream.forEach和Iterable.forEach方法,并在下一個代碼清單中進行演示。
StackWalker.getInstance().forEach(out::println);盡管JDK對Consumer , BiConsumer以及其他類型的標準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線程池延期執行一次
總結
以上是生活随笔為你收集整理的java线程池延期执行一次_Java使用者的延期执行的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 织梦幻灯片怎么调用(织梦幻灯片调用教程)
- 下一篇: 微信怎么链接网页(微信怎么链接网页打印)