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;//卖票逻辑@Overridepublic 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 {@Overridepublic 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();}}
