参考:
创建线程的三种方式_Callable和Runnable的区别
浅谈线程runnable和callable的使用及区别
三种方法
- 通过实现Runnable接口
- 通过继承Thread类
- 通过Callable和Future创建线程
Runnable和Callable异同
相同:
- 都是接口
- 都可以用来编写多线程
- 都需要Thread.start()启动
不同:
- Callable接口的任务线程能返回执行结果,而Runnable接口的任务线程不能返回结果。
- Callable接口的call方法允许抛出异常,而Runnable接口的run()方法只能在内部消化,不能抛出异常
注意:
Callable接口支持返回结果,需要通过FutureTast对象的get方法获得,需要阻塞主线程直到获取结果,不调用get则不会阻塞。
Callable的优势
多线程返回执行结果是一个很有用的特性,因为多线程相比单线程更难、更复杂的一个重要原因就是因为多线程充满着未知性,某条线程是否执行了?某条线程执行了多久?某条线程执行的时候我们期望的数据是否已经赋值完毕?无法得知,我们能做的只是等待这条多线程的任务执行完毕而已。而Callable+Future/FutureTask却可以获取多线程运行的结果,可以在等待时间太长没获取到需要的数据的情况下取消该线程的任务,真的是非常有用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
| import java.util.concurrent.Callable; import java.util.concurrent.FutureTask;
public class JavaTheadTest { public static final int COUNT = 100;
public static void main(String[] args) { new Thread(new MyThread(), "线程1,实现Runnable接口").start(); new Thread(new Runnable() { @Override public void run() { int count = COUNT; while (count > 0) { System.out.println("1. In Runnable"); count--; } } }, "线程1,实现Runnable接口,在调用处定义线程内容").start();
new MyThread2().start();
MyCallable myCallable = new MyCallable(); FutureTask<String> futureTask = new FutureTask<>(myCallable); String res = null;
try { new Thread(futureTask, "线程Callable").start(); res = futureTask.get();
} catch (Exception e) { e.printStackTrace(); } System.out.println(res);
}
}
class MyThread implements Runnable {
@Override public void run() { int count = JavaTheadTest.COUNT; while (count > 0) { System.out.println("2. In MyThread"); count--; } } }
class MyThread2 extends Thread { @Override public void run() { super.run();
int count = JavaTheadTest.COUNT; while (count > 0) { System.out.println("3. In MyThread2"); count--; }
} }
class MyCallable implements Callable<String> {
@Override public String call() throws Exception {
int count = JavaTheadTest.COUNT; while (count > 0) { System.out.println("4. In MyCallable"); count--; }
return "success"; }
}
|