﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-paulwong-随笔分类-多线程</title><link>http://www.blogjava.net/paulwong/category/55362.html</link><description /><language>zh-cn</language><lastBuildDate>Mon, 24 Aug 2020 10:18:49 GMT</lastBuildDate><pubDate>Mon, 24 Aug 2020 10:18:49 GMT</pubDate><ttl>60</ttl><item><title>Scheduling a task in Java within a CompletableFuture</title><link>http://www.blogjava.net/paulwong/archive/2020/08/24/435646.html</link><dc:creator>paulwong</dc:creator><author>paulwong</author><pubDate>Mon, 24 Aug 2020 01:06:00 GMT</pubDate><guid>http://www.blogjava.net/paulwong/archive/2020/08/24/435646.html</guid><wfw:comment>http://www.blogjava.net/paulwong/comments/435646.html</wfw:comment><comments>http://www.blogjava.net/paulwong/archive/2020/08/24/435646.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/paulwong/comments/commentRss/435646.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/paulwong/services/trackbacks/435646.html</trackback:ping><description><![CDATA[<p style="box-sizing: inherit; border: 0px; font-family: &quot;Noto Sans&quot;, sans-serif; font-size: 19px; margin: 0px 0px 1.6842em; outline: 0px; padding: 0px; vertical-align: baseline; color: #333333; background-color: #ffffff;">When we want to do something later in our Java code, we often turn to the&nbsp;<a href="https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/concurrent/ScheduledExecutorService.html" style="box-sizing: inherit; border-width: 0px 0px 1px; border-top-style: initial; border-right-style: initial; border-bottom-style: solid; border-left-style: initial; border-top-color: initial; border-right-color: initial; border-bottom-color: #333333; border-left-color: initial; border-image: initial; font-family: inherit; font-style: inherit; font-weight: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; color: #333333; text-decoration-line: none;">ScheduledExecutorService</a>. This class has a method called&nbsp;<tt style="box-sizing: inherit; border: 0px; font-family: Inconsolata, monospace; font-style: inherit; font-weight: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; hyphens: none;">schedule()</tt>, and we can pass it some code to be run later like this:<br /><br /></p><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->ScheduledExecutorService&nbsp;executor&nbsp;=<br />&nbsp;&nbsp;&nbsp;&nbsp;Executors.newScheduledThreadPool(4);<br />executor.schedule(<br />&nbsp;&nbsp;&nbsp;&nbsp;()&nbsp;-&gt;&nbsp;{System.out.println("..later");},<br />&nbsp;&nbsp;&nbsp;&nbsp;1,<br />&nbsp;&nbsp;&nbsp;&nbsp;TimeUnit.SECONDS<br />);<br />System.out.println("do<img src="http://www.blogjava.net/Images/dot.gif"  alt="" />");<br /><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;(Don't&nbsp;forget&nbsp;to&nbsp;shut&nbsp;down&nbsp;the&nbsp;executor&nbsp;later<img src="http://www.blogjava.net/Images/dot.gif"  alt="" />)</span></div><p style="box-sizing: inherit; border: 0px; font-family: &quot;Noto Sans&quot;, sans-serif; font-size: 19px; margin: 0px 0px 1.6842em; outline: 0px; padding: 0px; vertical-align: baseline; color: #333333; background-color: #ffffff;">The above code prints &#8220;do&#8230;&#8221; and then one second later it prints &#8220;&#8230;later&#8221;.</p><p style="box-sizing: inherit; border: 0px; font-family: &quot;Noto Sans&quot;, sans-serif; font-size: 19px; margin: 0px 0px 1.6842em; outline: 0px; padding: 0px; vertical-align: baseline; color: #333333; background-color: #ffffff;">We can even write code that does some work and returns a result in a similar way:<br /><br /></p><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;(Make&nbsp;the&nbsp;executor&nbsp;as&nbsp;above.)</span><span style="color: #008000; "><br /></span>ScheduledFuture&nbsp;future&nbsp;=&nbsp;executor.schedule(<br />&nbsp;&nbsp;&nbsp;&nbsp;()&nbsp;-&gt;&nbsp;10&nbsp;+&nbsp;25,&nbsp;1,&nbsp;TimeUnit.SECONDS);<br />System.out.println("answer="&nbsp;+&nbsp;future.get())</div><p style="box-sizing: inherit; border: 0px; font-family: &quot;Noto Sans&quot;, sans-serif; font-size: 19px; margin: 0px 0px 1.6842em; outline: 0px; padding: 0px; vertical-align: baseline; color: #333333; background-color: #ffffff;"><br />The above code prints &#8220;answer=35&#8221;. When we call&nbsp;<tt style="box-sizing: inherit; border: 0px; font-family: Inconsolata, monospace; font-style: inherit; font-weight: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; hyphens: none;">get()</tt>&nbsp;it blocks waiting for the scheduler to run the task and mark the&nbsp;<tt style="box-sizing: inherit; border: 0px; font-family: Inconsolata, monospace; font-style: inherit; font-weight: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; hyphens: none;">ScheduledFuture</tt>&nbsp;as complete, and then returns the answer to the sum (10 + 25) when it is ready.</p><p style="box-sizing: inherit; border: 0px; font-family: &quot;Noto Sans&quot;, sans-serif; font-size: 19px; margin: 0px 0px 1.6842em; outline: 0px; padding: 0px; vertical-align: baseline; color: #333333; background-color: #ffffff;">This is all very well, but you may note that the Future returned from&nbsp;<tt style="box-sizing: inherit; border: 0px; font-family: Inconsolata, monospace; font-style: inherit; font-weight: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; hyphens: none;">schedule()</tt>&nbsp;is a&nbsp;<tt style="box-sizing: inherit; border: 0px; font-family: Inconsolata, monospace; font-style: inherit; font-weight: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; hyphens: none;">ScheduledFuture</tt>, and a&nbsp;<tt style="box-sizing: inherit; border: 0px; font-family: Inconsolata, monospace; font-style: inherit; font-weight: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; hyphens: none;">ScheduledFuture</tt>&nbsp;is not a&nbsp;<tt style="box-sizing: inherit; border: 0px; font-family: Inconsolata, monospace; font-style: inherit; font-weight: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; hyphens: none;">CompletableFuture</tt>.</p><p style="box-sizing: inherit; border: 0px; font-family: &quot;Noto Sans&quot;, sans-serif; font-size: 19px; margin: 0px 0px 1.6842em; outline: 0px; padding: 0px; vertical-align: baseline; color: #333333; background-color: #ffffff;">Why do you care? Well, you might care if you want to do something after the scheduled task is completed. Of course, you can call get(), and block, and then do something, but if you want to react asynchronously without blocking, this won&#8217;t work.</p><p style="box-sizing: inherit; border: 0px; font-family: &quot;Noto Sans&quot;, sans-serif; font-size: 19px; margin: 0px 0px 1.6842em; outline: 0px; padding: 0px; vertical-align: baseline; color: #333333; background-color: #ffffff;">The normal way to run some code after a Future has completed is to call one of the &#8220;then*&#8221; or &#8220;when*&#8221; methods on the Future, but these methods are only available on&nbsp;<tt style="box-sizing: inherit; border: 0px; font-family: Inconsolata, monospace; font-style: inherit; font-weight: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; hyphens: none;">CompletableFuture</tt>, not&nbsp;<tt style="box-sizing: inherit; border: 0px; font-family: Inconsolata, monospace; font-style: inherit; font-weight: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; hyphens: none;">ScheduledFuture</tt>.</p><p style="box-sizing: inherit; border: 0px; font-family: &quot;Noto Sans&quot;, sans-serif; font-size: 19px; margin: 0px 0px 1.6842em; outline: 0px; padding: 0px; vertical-align: baseline; color: #333333; background-color: #ffffff;">Never fear, we have figured this out for you. We present a small wrapper for schedule that transforms your&nbsp;<tt style="box-sizing: inherit; border: 0px; font-family: Inconsolata, monospace; font-style: inherit; font-weight: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; hyphens: none;">ScheduledFuture</tt>&nbsp;into a&nbsp;<tt style="box-sizing: inherit; border: 0px; font-family: Inconsolata, monospace; font-style: inherit; font-weight: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; hyphens: none;">CompletableFuture</tt>. Here&#8217;s how to use it:<br /><br /></p><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->CompletableFuture&lt;Integer&gt;&nbsp;future&nbsp;=<br />&nbsp;&nbsp;&nbsp;&nbsp;ScheduledCompletable.schedule(<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;executor,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;()&nbsp;-&gt;&nbsp;10&nbsp;+&nbsp;25,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TimeUnit.SECONDS<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;);<br />future.thenAccept(<br />&nbsp;&nbsp;&nbsp;&nbsp;answer&nbsp;-&gt;&nbsp;{System.out.println(answer);}<br />);<br />System.out.println("Answer&nbsp;coming<img src="http://www.blogjava.net/Images/dot.gif"  alt="" />")</div><p style="box-sizing: inherit; border: 0px; font-family: &quot;Noto Sans&quot;, sans-serif; font-size: 19px; margin: 0px 0px 1.6842em; outline: 0px; padding: 0px; vertical-align: baseline; color: #333333; background-color: #ffffff;"><br />The above code prints &#8220;Answer coming&#8230;&#8221; and then &#8220;35&#8221;, so we can see that we don&#8217;t block the main thread waiting for the answer to come back.</p><p style="box-sizing: inherit; border: 0px; font-family: &quot;Noto Sans&quot;, sans-serif; font-size: 19px; margin: 0px 0px 1.6842em; outline: 0px; padding: 0px; vertical-align: baseline; color: #333333; background-color: #ffffff;">So far, we have scheduled a synchronous task to run in the background after a delay, and wrapped its result in a&nbsp;<tt style="box-sizing: inherit; border: 0px; font-family: Inconsolata, monospace; font-style: inherit; font-weight: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; hyphens: none;">CompletableFuture</tt>&nbsp;to allow us to chain more tasks after it.</p><p style="box-sizing: inherit; border: 0px; font-family: &quot;Noto Sans&quot;, sans-serif; font-size: 19px; margin: 0px 0px 1.6842em; outline: 0px; padding: 0px; vertical-align: baseline; color: #333333; background-color: #ffffff;">In fact, what we often want to do is schedule a delayed task that is itself asynchronous, and already returns a&nbsp;<tt style="box-sizing: inherit; border: 0px; font-family: Inconsolata, monospace; font-style: inherit; font-weight: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; hyphens: none;">CompletableFuture</tt>. In this case it feels particularly natural to get the result back as a&nbsp;<tt style="box-sizing: inherit; border: 0px; font-family: Inconsolata, monospace; font-style: inherit; font-weight: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; hyphens: none;">CompletableFuture</tt>, but with the current&nbsp;<tt style="box-sizing: inherit; border: 0px; font-family: Inconsolata, monospace; font-style: inherit; font-weight: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; hyphens: none;">ScheduledExecutorService</tt>&nbsp;interface we can&#8217;t easily do it.</p><p style="box-sizing: inherit; border: 0px; font-family: &quot;Noto Sans&quot;, sans-serif; font-size: 19px; margin: 0px 0px 1.6842em; outline: 0px; padding: 0px; vertical-align: baseline; color: #333333; background-color: #ffffff;">It&#8217;s OK, we&#8217;ve figured that out too:<br /><br /></p><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->Supplier&lt;CompletableFuture&lt;Integer&gt;&gt;&nbsp;asyncTask&nbsp;=&nbsp;()&nbsp;-&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;CompletableFuture.completedFuture(10&nbsp;+&nbsp;25);<br />CompletableFuture&lt;Integer&gt;&nbsp;future&nbsp;=<br />&nbsp;&nbsp;&nbsp;&nbsp;ScheduledCompletable.scheduleAsync(<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;executor,&nbsp;asyncTask,&nbsp;1,&nbsp;TimeUnit.SECONDS);<br />future.thenAccept(<br />&nbsp;&nbsp;&nbsp;&nbsp;answer&nbsp;-&gt;&nbsp;{System.out.println(answer);}<br />);<br />System.out.println("Answer&nbsp;coming<img src="http://www.blogjava.net/Images/dot.gif"  alt="" />")</div><p style="box-sizing: inherit; border: 0px; font-family: &quot;Noto Sans&quot;, sans-serif; font-size: 19px; margin: 0px 0px 1.6842em; outline: 0px; padding: 0px; vertical-align: baseline; color: #333333; background-color: #ffffff;"><br />The above code prints &#8220;Answer coming&#8230;&#8221; and then &#8220;35&#8221;, so we can see that our existing asynchronous task was scheduled in the background, and we didn&#8217;t have to block the main thread waiting for it. Also, under the hood, we are not blocking the&nbsp;<tt style="box-sizing: inherit; border: 0px; font-family: Inconsolata, monospace; font-style: inherit; font-weight: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; hyphens: none;">ScheduledExecutorService</tt>&#8216;s thread (from its pool) while the async task is running &#8211; that task just runs in whatever thread it was assigned when it was created. (Note: in our example we don&#8217;t really run an async task at all, but just immediately return a completed Future, but this does work for real async tasks.)</p><p style="box-sizing: inherit; border: 0px; font-family: &quot;Noto Sans&quot;, sans-serif; font-size: 19px; margin: 0px 0px 1.6842em; outline: 0px; padding: 0px; vertical-align: baseline; color: #333333; background-color: #ffffff;">I know you&#8217;re wondering how we achieved all this. First, here&#8217;s how we run a simple blocking task in the background and wrap it in a&nbsp;<tt style="box-sizing: inherit; border: 0px; font-family: Inconsolata, monospace; font-style: inherit; font-weight: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; hyphens: none;">CompletableFuture</tt>:</p><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">static</span>&nbsp;&lt;T&gt;&nbsp;CompletableFuture&lt;T&gt;&nbsp;schedule(<br />&nbsp;&nbsp;&nbsp;&nbsp;ScheduledExecutorService&nbsp;executor,<br />&nbsp;&nbsp;&nbsp;&nbsp;Supplier&lt;T&gt;&nbsp;command,<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">long</span>&nbsp;delay,<br />&nbsp;&nbsp;&nbsp;&nbsp;TimeUnit&nbsp;unit<br />)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;CompletableFuture&lt;T&gt;&nbsp;completableFuture&nbsp;=&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;CompletableFuture&lt;&gt;();<br />&nbsp;&nbsp;&nbsp;&nbsp;executor.schedule(<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(()&nbsp;-&gt;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">try</span>&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;completableFuture.complete(command.get());<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<span style="color: #0000FF; ">catch</span>&nbsp;(Throwable&nbsp;t)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;completableFuture.completeExceptionally(t);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}),<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delay,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unit<br />&nbsp;&nbsp;&nbsp;&nbsp;);<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;completableFuture;<br />}</div><p style="box-sizing: inherit; border: 0px; font-family: &quot;Noto Sans&quot;, sans-serif; font-size: 19px; margin: 0px 0px 1.6842em; outline: 0px; padding: 0px; vertical-align: baseline; color: #333333; background-color: #ffffff;"><br />And here&#8217;s how we delay execution of an async task but still return its result in a&nbsp;<tt style="box-sizing: inherit; border: 0px; font-family: Inconsolata, monospace; font-style: inherit; font-weight: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; hyphens: none;">CompletableFuture</tt>:<br /><br /></p><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">static</span>&nbsp;&lt;T&gt;&nbsp;CompletableFuture&lt;T&gt;&nbsp;scheduleAsync(<br />&nbsp;&nbsp;&nbsp;&nbsp;ScheduledExecutorService&nbsp;executor,<br />&nbsp;&nbsp;&nbsp;&nbsp;Supplier&lt;CompletableFuture&lt;T&gt;&gt;&nbsp;command,<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">long</span>&nbsp;delay,<br />&nbsp;&nbsp;&nbsp;&nbsp;TimeUnit&nbsp;unit<br />)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;CompletableFuture&lt;T&gt;&nbsp;completableFuture&nbsp;=&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;CompletableFuture&lt;&gt;();<br />&nbsp;&nbsp;&nbsp;&nbsp;executor.schedule(<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(()&nbsp;-&gt;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;command.get().thenAccept(<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;t&nbsp;-&gt;&nbsp;{completableFuture.complete(t);}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.exceptionally(<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;t&nbsp;-&gt;&nbsp;{completableFuture.completeExceptionally(t);<span style="color: #0000FF; ">return</span>&nbsp;<span style="color: #0000FF; ">null</span>;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}),<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delay,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unit<br />&nbsp;&nbsp;&nbsp;&nbsp;);<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;completableFuture;<br />}</div><p style="box-sizing: inherit; border: 0px; font-family: &quot;Noto Sans&quot;, sans-serif; font-size: 19px; margin: 0px 0px 1.6842em; outline: 0px; padding: 0px; vertical-align: baseline; color: #333333; background-color: #ffffff;"><br />Note that this should all work to run methods like&nbsp;<tt style="box-sizing: inherit; border: 0px; font-family: Inconsolata, monospace; font-style: inherit; font-weight: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; hyphens: none;">exceptionally()</tt>,&nbsp;<tt style="box-sizing: inherit; border: 0px; font-family: Inconsolata, monospace; font-style: inherit; font-weight: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; hyphens: none;">thenAccept()</tt>,&nbsp;<tt style="box-sizing: inherit; border: 0px; font-family: Inconsolata, monospace; font-style: inherit; font-weight: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; hyphens: none;">whenComplete()</tt>&nbsp;etc.</p><p style="box-sizing: inherit; border: 0px; font-family: &quot;Noto Sans&quot;, sans-serif; font-size: 19px; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; color: #333333; background-color: #ffffff;">Feedback and improvements welcome!</p><br /><a href="https://www.artificialworlds.net/blog/2019/04/05/scheduling-a-task-in-java-within-a-completablefuture/" target="_blank">https://www.artificialworlds.net/blog/2019/04/05/scheduling-a-task-in-java-within-a-completablefuture/</a><img src ="http://www.blogjava.net/paulwong/aggbug/435646.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/paulwong/" target="_blank">paulwong</a> 2020-08-24 09:06 <a href="http://www.blogjava.net/paulwong/archive/2020/08/24/435646.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>CompletableFuture</title><link>http://www.blogjava.net/paulwong/archive/2020/08/14/435641.html</link><dc:creator>paulwong</dc:creator><author>paulwong</author><pubDate>Fri, 14 Aug 2020 03:46:00 GMT</pubDate><guid>http://www.blogjava.net/paulwong/archive/2020/08/14/435641.html</guid><wfw:comment>http://www.blogjava.net/paulwong/comments/435641.html</wfw:comment><comments>http://www.blogjava.net/paulwong/archive/2020/08/14/435641.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/paulwong/comments/commentRss/435641.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/paulwong/services/trackbacks/435641.html</trackback:ping><description><![CDATA[很久以前多线程是这样创建：<br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->Thread&nbsp;t1&nbsp;=&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;Thread();<br />Thread&nbsp;t2&nbsp;=&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;Thread();<br />t1.start();&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;启动新线程</span><span style="color: #008000; "><br /></span>t2.start();&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;启动新线程</span></div><br />由于创建和销毁线程是非常耗资源，因此改成线程建好后不销毁，可以重用，用户只需提供run方法的具体实现：<br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">static</span>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;main(String[]&nbsp;args)&nbsp;<span style="color: #0000FF; ">throws</span>&nbsp;Exception&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ExecutorService&nbsp;executor&nbsp;=&nbsp;Executors.newSingleThreadExecutor();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Future&lt;String&gt;&nbsp;stringFuture&nbsp;=&nbsp;executor.submit(<span style="color: #0000FF; ">new</span>&nbsp;Callable&lt;String&gt;()&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@Override<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;String&nbsp;call()&nbsp;<span style="color: #0000FF; ">throws</span>&nbsp;Exception&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Thread.sleep(2000);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;"async&nbsp;thread";<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;});<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Thread.sleep(1000);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("main&nbsp;thread");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(stringFuture.get());<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;}</div><br />但如果很多线程被创建，并且线程间有依赖，即按流程和条件执行线程，实现起来就有点复杂，于是CompletableFuture横空出世。一共有50各方法可供使用。<br /><div>CompletableFuture.supplyAsync()，相当于创建了ExecutorService，同时也创建了Callable，然后提交到线程池中执行。</div><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->CompletableFuture&lt;String&gt;&nbsp;futureA&nbsp;=&nbsp;CompletableFuture.supplyAsync(()&nbsp;-&gt;&nbsp;"任务A");<br />CompletableFuture&lt;String&gt;&nbsp;futureB&nbsp;=&nbsp;CompletableFuture.supplyAsync(()&nbsp;-&gt;&nbsp;"任务B");<br />CompletableFuture&lt;String&gt;&nbsp;futureC&nbsp;=&nbsp;futureB.thenApply(b&nbsp;-&gt;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("执行任务C.");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("参数:"&nbsp;+&nbsp;b);<span style="color: #008000; ">//</span><span style="color: #008000; ">参数:任务B</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;"a";<br />});</div><br /><br />!!How to use CompletableFuture and Callable in Java<br /><a href="https://ducmanhphan.github.io/2020-02-10-How-to-use-CompletableFuture-Callable-in-Java/" target="_blank">https://ducmanhphan.github.io/2020-02-10-How-to-use-CompletableFuture-Callable-in-Java/</a><br /><br />使用CompletableFuture优化你的代码执行效率<br /><a href="https://www.cnblogs.com/fingerboy/p/9948736.html" target="_blank">https://www.cnblogs.com/fingerboy/p/9948736.html</a><br /><br />CompletableFuture 使用详解<br /><a href="https://www.jianshu.com/p/6bac52527ca4" target="_blank">https://www.jianshu.com/p/6bac52527ca4</a><br /><br />使用CompletableFuture<br /><a href="https://www.liaoxuefeng.com/wiki/1252599548343744/1306581182447650" target="_blank">https://www.liaoxuefeng.com/wiki/1252599548343744/1306581182447650</a><br /><br /><br /><a href="https://github.com/eugenp/tutorials/blob/master/core-java-modules/core-java-concurrency-basic/src/test/java/com/baeldung/completablefuture/CompletableFutureLongRunningUnitTest.java" target="_blank">https://github.com/eugenp/tutorials/blob/master/core-java-modules/core-java-concurrency-basic/src/test/java/com/baeldung/completablefuture/CompletableFutureLongRunningUnitTest.java</a><img src ="http://www.blogjava.net/paulwong/aggbug/435641.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/paulwong/" target="_blank">paulwong</a> 2020-08-14 11:46 <a href="http://www.blogjava.net/paulwong/archive/2020/08/14/435641.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>