8、Callable

多线程中 , 三种获得多线程的方式

1、继承Thread类
2、实现Runnable接口
3、实现 Callable接口

Callable与Runnable的区别

 //创建新类MyThread实现runnable接口
class MyThread implements Runnable{
 @Override
 public void run() {
 
 }
}
//新类MyThread2实现callable接口
class MyThread2 implements Callable<Integer>{
 @Override
 public Integer call() throws Exception {
  return 200;
 } 
}


Callable可以有返回值 可以检查异常 可以细粒度化的对多线程进行控制和管理

实例使用代码


Callable实现方式

Thread不能直接调用Callable的实现类 因为 thread类的构造方法根本没有Callable

但是从中可以分析出 Thread类的构造方法需要实现Runable接口的实现类
通过 java多态的思想,一个类可以实现多个接口!!

class MyThread implements Callable<Integer> {

	@Override
	public Integer call() throws Exception {
		System.out.println("-----Callable here");
		return 200;
	}
}
public class CallableDemo {
	public static void main(String[] args) throws ExecutionException, InterruptedException {
		MyThread myThread = new MyThread();
		FutureTask futureTask= new FutureTask(myThread);
		Thread t1 = new Thread(futureTask);
		t1.start();
		System.out.println(futureTask.get());
		// 结果
		// -----Callable here
		// 200
	}
}


线程再处理一系列问题的时候
如果遇到比较困难的问题 另起一个线程(Callable)去处理这个困难问题
原线程继续解决其他问题
当两个线程的问题都解决完了 再进行汇总 (get方法获取Callable的返回值)

原理上理解FutureTask

1、在主线程中需要执行比较耗时的操作时,但又不想阻塞主线程时,可以把这些作业交给Future对象在后台完成,
当主线程将来需要时,就可以通过Future对象获得后台作业的计算结果或者执行状态。
2、一般FutureTask多用于耗时的计算,主线程可以在完成自己的任务后,再去获取结果。
3、仅在计算完成时才能检索结果;如果计算尚未完成,则阻塞 get 方法。一旦计算完成,
就不能再重新开始或取消计算。get方法而获取结果只有在计算完成时获取,否则会一直阻塞直到任务转入完成状态,
4、然后会返回结果或者抛出异常。

两个或多个线程进行调用同一个Callable接口的call()方法只计算一次
(可以理解为 比如让Callable接口去计算 1 + 1 计算结果已经知道是2了 在调用一次 就不在进行计算了)
get方法一般放在最后一行

原文地址:https://www.cnblogs.com/xidianzxm/p/14298739.html