Thread
类通过继承Thread
类,重写run()
通过Thread
类创建线程对象,将Runnable
实例作为实际参数传入。构造方法如下
public Thread(Runnable target) {
init(null, target, "Thread-" + nextThreadNum(), 0);
}
Callable
和FutureTask
实现FutureTask
FutureTask
类解释// 一:
FutureTask<V> implements RunnableFuture<V>
//带Callable 参数构造方法
public FutureTask(Callable<V> callable) {
if (callable == null)
throw new NullPointerException();
this.callable = callable;
this.state = NEW; // ensure visibility of callable
}
// 二:通过Future接口获得——》阻塞线程,获取返回结果等能力;
//线程的目标调用还是在Runnable中
interface RunnableFuture<V> extends Runnable, Future<V>
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;
}
public class Demo1 {
public static final int COMPUTE_TIMES = 100000000;
//①创建一个 Callable 接口的实现类(只是单纯的一个接口,异步还是通过runnable 实现的)
static class CallableImpl implements Callable<Long> {
//②编写好异步执行的具体逻辑,可以有返回值
public Long call() throws Exception {
long startTime = System.currentTimeMillis();
System.out.println(getCurThreadName() + " 线程运行开始.");
Thread.sleep(888);
for (int i = 0; i < COMPUTE_TIMES; i++) {
int j = i * 10000;
}
long used = System.currentTimeMillis() - startTime;
System.out.println(getCurThreadName() + " 线程运行结束.");
return used;
}
}
public static void main(String args[]) throws InterruptedException {
CallableImpl task = new CallableImpl();
FutureTask<Long> futureTask = new FutureTask<Long>(task);
Thread thread = new Thread(futureTask, "return-Thread");//⑤
thread.start();
//⑥
Thread.sleep(500);
System.out.println(getCurThreadName() + " 干自己线程的事情.");
for (int i = 0; i < COMPUTE_TIMES / 2; i++) {
int j = i * 10000;
}
System.out.println(getCurThreadName() + " 准备获取并发任务的执行结果.");
try {
//futureTask.get() 会阻塞。
System.out.println(thread.getName() + "return-Thread线程执行结果;线程占用时间:" + futureTask.get());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
System.out.println(getCurThreadName() + " 运行结束.");
}
static String getCurThreadName() {
return Thread.currentThread().getName();
}
注释:调用start(),会执行futureTask 中的run() ,再调用 call.call();
线程的创建销毁都需要成本,因此需要对创建好的线程实例复用,进而引入了线程池。
通过Executors
调用静态方法创建