我们已经知道,在JavaSE中,有两种方式实现多线程:
1:继承Thread实现多线程
2:runnable()接口实现多线程
在JDK1.5以前,主要是这两种方法来实现多线程,在JDK1.5以后,引入了新的开发包java.util.concurrent。这个开发包主要是针对高并发编程使用的,包含了很多在高并发操作中使用的类,包中定义了一个新的接口Callable。
使用Callable接口创建线程时是存在返回值的,如果我们想在某些线程执行完之后返回一些结果,那么就只能利用Callable接口来实现多线程。
这是Callable接口的源码:
@FunctionalInterface
public interface Callable<V> {
/**
* Computes a result, or throws an exception if unable to do so.
*
* @return computed result
* @throws Exception if unable to compute a result
*/
V call() throws Exception;
}
因为Callable实现多线程很复杂,所以先上一张流程图
首先,先介绍几个类与接口
MyThread:实现了Callable的子类。
Thread:JDK1.0提供的有关线程操作的核心类。
Runnable接口:Thread类继承于它
@FunctionalInterface
public interface Runnable {
/**
* When an object implementing interface <code>Runnable</code> is used
* to create a thread, starting the thread causes the object's
* <code>run</code> method to be called in that separately executing
* thread.
* <p>
* The general contract of the method <code>run</code> is that it may
* take any action whatsoever.
*
* @see java.lang.Thread#run()
*/
public abstract void run();
}
public
class Thread implements Runnable
RunnableFuture接口:继承于Runnable接口,同时也继承于Future接口
public interface RunnableFuture<V> extends Runnable, Future<V> {
/**
* Sets this Future to the result of its computation
* unless it has been cancelled.
*/
void run();
}
Future接口:这个接口里的get()方法可以取得callable接口里的返回值
V call() throws Exception;
Future Task :实现RunnableFuture接口的类,此类的构造方法里含有Callable<T>类型的参数
public class FutureTask<V> implements RunnableFuture<V>
public FutureTask(Callable<V> callable) {
if (callable == null)
throw new NullPointerException();
this.callable = callable;
this.state = NEW; // ensure visibility of callable
}
Callable接口
@FunctionalInterface
public interface Callable<V> {
/**
* Computes a result, or throws an exception if unable to do so.
*
* @return computed result
* @throws Exception if unable to compute a result
*/
V call() throws Exception;
}
现在我们来理一下思路,首先我们创建一个类MyThread类继承Thread类。现在我们把目光稍微转移一下,先看一下
Future Task类,这个类实现了RunnableFuture接口,同时RunnableFuture接口是Runnable接口的子接口,Thread类实现了Runnable接口,同时,Future Task类里的构造方法接收Callable<T>的参数。My_Thread是Thread的子类,所以我们可以把My_Thread类当作Callable<T>传到Future Task的构造方法里。最后的代码如下。
class MyThread implements Callable<String>{
private int number = 10;
@Override
public String call() {
while(this.number>0){
System.out.println(this.number--);
}
return "数字为0";
}
}
public class Main{
public static void main(String[] args)throws InterruptedException,ExecutionException{
FutureTask<String> task = new FutureTask<>(new MyThread());*
new Thread(task).start();
System.out.println(task.get());
}
}
这样就用Callable接口创建了一个新线程。
我先总结到这里,如果还有更多的总结我会及时补充。