Java线程—-Runnable和Callable的区别和联系

Java 提供了三种创建线程的方法
1.继承Thread接口

 1 public class Thread2Thread {
 2     public static void main(String[] args) {
 3         new MyThread1().start();
 4         new Thread(new MyThread1(), "线程2").start();
 5     }
 6 }
 7 
 8 /**
 9  * 通过继承Thread类
10  */
11 class MyThread1 extends Thread {
12     /**
13      * 重写run方法
14      */
15     @Override
16     public void run() {
17         // TODO Auto-generated method stub
18         super.run();
19     }
20 }
通过继承Thread类

2.实现Runnable接口

 1 package com.testthread.demo4;
 2 
 3 import java.util.concurrent.ExecutorService;
 4 
 5 import static java.util.concurrent.Executors.*;
 6 
 7 public class Thread2Runnable {
 8 
 9     public static void main(String[] args) {
10 
11         //case1:通过实现Runnable接口,来实现run方法的具体逻辑
12         new Thread(new MyThread2(), "线程1").start();
13         //case2:匿名内部类
14         new Thread(new Runnable() {
15             @Override
16             public void run() {
17                 // TODO Auto-generated method stub
18 
19             }
20         }, "线程2").start();
21 
22         //其实case1和case2的本质是一样的
23         
24         //case3:作为线程任务提交给线程池,通过线程池维护的工作者线程来执行。
25         ExecutorService executor = newCachedThreadPool();
26         MyThread2 myThread2 = new MyThread2();
27         executor.execute(myThread2);
28         executor.shutdown();
29     }
30 }
31 
32 /**
33  * 实现Runnable接口的线程类
34  */
35 class MyThread2 implements Runnable {
36 
37     /**
38      * 重写run方法
39      */
40     @Override
41     public void run() {
42         // TODO Auto-generated method stub
43     }
44 }
实现Runnable接口

3.通过Callable和Future创建线程

 1 import java.util.concurrent.Callable;
 2 import java.util.concurrent.FutureTask;
 3 
 4 public class Thread2Callable {
 5     public static void main(String[] args) {
 6         //创建 Callable 实现类的实例
 7         MyCallable myCallable = new MyCallable();
 8         //使用 FutureTask 类来包装 Callable 对象,该 FutureTask 对象封装了该 Callable 对象的 call() 方法的返回值
 9         FutureTask<String> futureTask = new FutureTask<String>(myCallable);
10         String res = null;
11         try {
12             //使用 FutureTask 对象作为 Thread 对象的 target 创建并启动新线程
13             //没这句,下句代码获取不到结果,会一直等待执行结果
14             new Thread(futureTask,"线程1").start();
15             //调用 FutureTask 对象的 get() 方法来获得子线程执行结束后的返回值
16             res = futureTask.get();
17         } catch (Exception e) {
18             e.printStackTrace();
19         }
20         System.out.println(res);
21     }
22 }
23 /**
24  * 创建 Callable 接口的实现类,并实现 call() 方法
25  */
26 class MyCallable implements Callable<String> {
27 
28     /**
29      * 该 call() 方法将作为线程执行体,并且有返回值
30      */
31     @Override
32     public String call() throws Exception {
33         return "success";
34     }
35 }
通过Callable和Future创建线程

Runnable和Callable的区别和联系

接口定义

  Runnable  

其中Runnable应该是我们最熟悉的接口,它只有一个run()函数,用于将耗时操作写在其中,该函数没有返回值。然后使用某个线程去执行该runnable即可实现多线程,Thread类在调用start()函数后就是执行的是Runnable的run()函数。

Runnable的声明如下 :

1 public interface Runnable {
2     /*
3      * @see     java.lang.Thread#run()
4      */
5     public abstract void run();
6 }
Runnable

  #Callable

Callable与Runnable的功能大致相似,Callable中有一个call()函数,但是call()函数有返回值,而Runnable的run()函数不能将结果返回给客户程序。

Callable的声明如下 :

1 public interface Callable<V> {
2     /**
3      * Computes a result, or throws an exception if unable to do so.
4      *
5      * @return computed result
6      * @throws Exception if unable to compute a result
7      */
8     V call() throws Exception;
9 }
View Code

  #Future

Executor就是Runnable和Callable的调度容器,Future就是对于具体的Runnable或者Callable任务的执行结果进行
取消、查询是否完成、获取结果、设置结果操作。get方法会阻塞,直到任务返回结果(Future简介)。

Future声明如下 :

 1 public interface Future<V> {
 2  
 3     /**
 4      * Attempts to cancel execution of this task.  This attempt will
 5      * fail if the task has already completed, has already been cancelled,
 6      * or could not be cancelled for some other reason. If successful,
 7      * and this task has not started when <tt>cancel</tt> is called,
 8      * this task should never run.  If the task has already started,
 9      * then the <tt>mayInterruptIfRunning</tt> parameter determines
10      * whether the thread executing this task should be interrupted in
11      * an attempt to stop the task.
12      */
13     boolean cancel(boolean mayInterruptIfRunning);
14  
15     /**
16      * Returns <tt>true</tt> if this task was cancelled before it completed
17      * normally.
18      */
19     boolean isCancelled();
20  
21     /**
22      * Returns <tt>true</tt> if this task completed.
23      *
24      */
25     boolean isDone();
26  
27     /**
28      * Waits if necessary for the computation to complete, and then
29      * retrieves its result.
30      *
31      * @return the computed result
32      */
33     V get() throws InterruptedException, ExecutionException;
34  
35     /**
36      * Waits if necessary for at most the given time for the computation
37      * to complete, and then retrieves its result, if available.
38      *
39      * @param timeout the maximum time to wait
40      * @param unit the time unit of the timeout argument
41      * @return the computed result
42      */
43     V get(long timeout, TimeUnit unit)
44         throws InterruptedException, ExecutionException, TimeoutException;
45 }
Future

#FutureTask(很有用)

  FutureTask是一个RunnableFuture<V>  

1 public class FutureTask<V> implements RunnableFuture<V>
FutureTask

猜你喜欢

转载自www.cnblogs.com/zt007/p/10339203.html