视频:https://edu.aliyun.com/course/36/learn?spm=5176.8764728.0.0.fVZ5cb#lesson/433
1.从JDK1.5开始,追加了一个新的开发包:java.util.concurrent,这个开发包主要是进行高性能编程使用的,即这个开发包中会提供一些高并发操作中才会使用的类。在这个包里面定义有一个新的接口:
public interface Callable<V> { public V call() throws Exception; }
Runnable中的run()方法虽然也是线程的主方法,但是其没有返回值,因为它的设计遵循了主方法的原则,即线程开始了就别回头。但是很多时候需要一些返回值,例如:当某些线程执行完成后有可能带来一些返回结果,这种情况下就只能通过Callable来实现多线程。(JDK中的描述:Callable 接口类似于 Runnable
,两者都是为那些其实例可能被另一个线程执行的类设计的。但是 Runnable 不会返回结果,并且无法抛出经过检查的异常。)
范例:使用Callable定义线程主体类
class MyThread implements Callable<String>{ @Override public String call() throws Exception { for(int x=0;x<20;x++){ System.out.println("卖票,x"+x); } return "票卖完了"; } } //这个就是一个线程的主体类了
public class MyThread222 {
public static void main(String[] args) {
}
}
不管何种情况,如果要想启动多线程只有Thread类的start()方法,分析Callable接口的定义,FutureTask类可接收Callable,可使用 FutureTask 包装 Callable
或 Runnable
对象。因为 FutureTask 实现了 Runnable,所以可将 FutureTask 提交给 Executor
执行。
范例:启动并获取多线程的结果
import java.util.concurrent.*; class MyThread implements Callable<String>{ @Override public String call() throws Exception { for(int x=0;x<20;x++){ System.out.println("卖票,x="+x); } return "票卖完了"; } } public class TestDemo { public static void main(String[] args) throws Exception{ FutureTask<String> task=new FutureTask(new MyThread()); new Thread(task).start();//启动多线程 System.out.println(task.get()); } }
这种形式主要是返回处理结果。