文档

java体系技术文档


多线程

<h1>多线程</h1> <h2>1 Runnable、Callable和Future</h2> <h3>1.1 Runnable和Callable</h3> <p>Callable是类似于Runnable的接口,实现Callable接口的类和实现Runnable的类都是可被其它线程执行的任务。</p> <ul> <li>Runnable需要重写run()方法,Callable需要重写call()方法;</li> <li>Runnable任务执行后没有返回值,Callable执行任务后有返回值;</li> <li>run()方法不可以抛出异常,call()方法可以抛出异常;</li> </ul> <h3>1.2 Future</h3> <p>Future就是对于具体的Runnable或者Callable任务的执行结果进行取消、查询是否完成、获取结果。必要时可以通过get方法获取执行结果,该方法会阻塞直到任务返回结果。 Future接口:</p> <pre><code class="language-java">public interface Future&lt;V&gt; { boolean cancel(boolean mayInterruptIfRunning);//取消任务 boolean isCancelled();//是否已经取消任务 boolean isDone();//是否已经完成任务 V get() throws InterruptedException, ExecutionException;//获取结果,阻塞 V get(long timeout, TimeUnit unit)//获取结果,设置超时,超时返回null throws InterruptedException, ExecutionException, TimeoutException; }</code></pre> <h3>1.3 FutureTask</h3> <p>FutureTask的实现:</p> <pre><code>public class FutureTask&lt;V&gt; implements RunnableFuture&lt;V&gt;</code></pre> <p>RunnableFuture的实现:</p> <pre><code class="language-java">public interface RunnableFuture&lt;V&gt; extends Runnable, Future&lt;V&gt; { void run(); }</code></pre> <p>可以看出RunnableFuture继承了Runnable接口和Future接口,而FutureTask实现了RunnableFuture接口。所以它既可以作为Runnable被线程执行,又可以作为Future得到Callable的返回值。</p> <p>FutureTask提供了2个构造器:</p> <pre><code>public FutureTask(Callable&lt;V&gt; callable) {} public FutureTask(Runnable runnable, V result) {}</code></pre> <h3>1.4 demo</h3> <ul> <li> <p>使用Callable+Future获取执行结果</p> <pre><code class="language-java">public class Test { public static void main(String[] args) { ExecutorService executor = Executors.newCachedThreadPool(); Task task = new Task(); Future&lt;Integer&gt; result = executor.submit(task); executor.shutdown(); try { Thread.sleep(1000); } catch (InterruptedException e1) { e1.printStackTrace(); } System.out.println("主线程在执行任务"); try { System.out.println("task运行结果"+result.get()); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } System.out.println("所有任务执行完毕"); } } class Task implements Callable&lt;Integer&gt;{ @Override public Integer call() throws Exception { System.out.println("子线程在进行计算"); Thread.sleep(3000); int sum = 0; for(int i=0;i&lt;100;i++) sum += i; return sum; } }</code></pre> </li> <li> <p>使用Callable+FutureTask获取执行结果</p> <pre><code class="language-java">public class Test { public static void main(String[] args) { //第一种方式 ExecutorService executor = Executors.newCachedThreadPool(); Task task = new Task(); FutureTask&lt;Integer&gt; futureTask = new FutureTask&lt;Integer&gt;(task); executor.submit(futureTask); executor.shutdown(); //第二种方式,注意这种方式和第一种方式效果是类似的,只不过一个使用的是ExecutorService,一个使用的是Thread /*Task task = new Task(); FutureTask&lt;Integer&gt; futureTask = new FutureTask&lt;Integer&gt;(task); Thread thread = new Thread(futureTask); thread.start();*/ try { Thread.sleep(1000); } catch (InterruptedException e1) { e1.printStackTrace(); } System.out.println("主线程在执行任务"); try { System.out.println("task运行结果"+futureTask.get()); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } System.out.println("所有任务执行完毕"); } } class Task implements Callable&lt;Integer&gt;{ @Override public Integer call() throws Exception { System.out.println("子线程在进行计算"); Thread.sleep(3000); int sum = 0; for(int i=0;i&lt;100;i++) sum += i; return sum; } }</code></pre> </li> </ul>

页面列表

ITEM_HTML