Callable是一个接口
两种方式是手动创建线程:thread类和runnable接口,但是这两个创建方式缺少一个功能,当线程终止的时候(run方法运行结束)的时候,我们无法得到返回值,为了支持这个功能,Java中提供了一个Callable接口。
如果需要完成并且获得结果就使用call()方法,注意:不能使用Callable创建线程,只能使用Runnable创建线程
call方法会抛出一个异常,run没有异常
为实现Callable接口必须重写call方法。
call方法需要注意的问题:
定义一个线程执行的目标逻辑
- 定义线程执行的目标:
这里我们是用卖票的案例模拟 向线程池提交任务:
a. F<?> submit((Runnable task)):接收一个Runnable接口实现类, 执行线程的目标b. Future
submit(Callable task):接收的是一个Callable接口实现类,执行线程目标
Future:任务的结果
V get()throws:ExecutionException, InterruptedException :返回的是一个call 的结果
package Test22_Demo.Demo02;/*
@create 2020--12--14--16:29
*/
/**
* 这是一个任务类
* 使用第二种方式 - 实现Runnable接口
*/
public class Ticket implements Runnable{
//定义车票
private int number = 100;
//卖票逻辑
@Override
public void run() {
//模拟车站不停的买票
while (true) {
//有票就卖
if (number > 0) {
System.out.println(Thread.currentThread().getName() + "正在销售第" + (number--) + "票");
} else {
//没有票了
break;
}
}
}
}
package Test22_Demo.Demo02;/*
@create 2020--12--15--10:03
*/
import java.util.concurrent.Callable;
public class MyCallable implements Callable {
@Override
public Object call() throws Exception {
return "我是线程任务的返回值结果";
}
}
package Test22_Demo.Demo02;/*
@create 2020--12--15--9:32
*/
import Test22_Demo.Demo01.Ticket;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class ThreadPoolDemo {
public static void main(String[] args) throws ExecutionException, InterruptedException {
//实例化线程
ExecutorService threadDemo = Executors.newFixedThreadPool(3);
//创建线程的执行目标
Ticket ticket = new Ticket();
/*threadDemo.submit(ticket);
threadDemo.submit(ticket);
threadDemo.submit(ticket);
threadDemo.submit(ticket);
threadDemo.submit(ticket);*/
//利用Callable接口返回Future,没有返回值的run方法,返回的是null,没有意义
Future<?> submit = threadDemo.submit(ticket);
System.out.println(submit.get());
//创建带有返回值的线程执行目标
MyCallable callable = new MyCallable();
//向线程中提交任务,并且返回线程目标的执行结果
Future<String> future1 = threadDemo.submit(callable);
Future<String> future2 = threadDemo.submit(callable);
Future<String> future3 = threadDemo.submit(callable);
//冲执行的结果返回call的具体值
String result1 = future1.get();
String result2 = future1.get();
String result3 = future1.get();
System.out.println(result1);
System.out.println(result2);
System.out.println(result3);
//在适当的时候可以关闭线程池,一般不关闭 - 因为反而会影响性能
//意味着线程池中的所有的线程都能销毁
//threadPool。shutdown();
}
}