【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>
Thread、Runnable 实现的是void run()方法,Callable实现的是 V call()方法,并且可以返回执行结果,其中Runnable可以提交给Thread来包装下,直接启动一个线程来执行,而Callable则一般都是提交给ExecuteService来执行。
Future就是对于具体的调度任务的执行结果进行查看,最为关键的是Future可以检查对应的任务是否已经完成,也可以阻塞在get方法上一直等待任务返回结果。Runnable和Callable的差别就是Runnable是没有结果可以返回的.
FutureTask则是一个RunnableFuture<V>,即实现了Runnbale又实现了Futrue<V>这两个接口,另外它还可以包装Runnable和Callable<V>,所以一般来讲是一个综合体了,它可以通过Thread包装来直接执行,也可以提交给ExecuteService来执行,并且还可以通过v get()返回执行结果,在线程体没有执行完成的时候,主线程一直阻塞等待,执行完则直接返回结果。
package test;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
/**
* 测试Thread ,Runnable,Callable <br>
* FutureTask 实现了RunnableFuture<V>,是个综合体。<br>
* 以上所有多线程操作都会出现线程安全问题,需要特别处理。
*
* @author Yuanqy
*
*/
public class TestThread {
public static void main(String[] args) {
try {
MyThread1 t1 = new MyThread1();// Thread
MyThread2 t2 = new MyThread2();// Runnable
MyThread3 t3 = new MyThread3();// Callable ==>Future
MyThread3 tft = new MyThread3();// Callable ==>FutureTask
ExecutorService es = Executors.newFixedThreadPool(100);
for (int i = 0; i < 2; i++) {
es.execute(t1);
es.execute(t2);
Future f1 = es.submit(t3);
System.err.println("Future:" + f1.get());// get是阻塞的
FutureTask ft = new FutureTask<Integer>(tft);// 使得Callable能用Runnable驱动
es.execute(ft);
System.err.println("FutureTask:" + ft.get());// get是阻塞的
}
} catch (Exception e) {
e.printStackTrace();
}
}
static class MyThread1 extends Thread {
private int ticket = 0;
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("[Thread]" + Thread.currentThread().getName() + ":" + (++ticket));
}
}
}
static class MyThread2 implements Runnable {
private int ticket = 0;
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("[Runnable]" + Thread.currentThread().getName() + ":" + (++ticket));
}
}
}
static class MyThread3 implements Callable<Integer> {
private int ticket = 0;
@Override
public Integer call() throws Exception {
for (int i = 0; i < 10; i++) {
System.out.println("[Callable]" + Thread.currentThread().getName() + ":" + (++ticket));
}
return new Integer(ticket);// 有返回值
}
}
}