1. FutureTask的用法
在Java中,一般是通过继承Thread类或者实现Runnable接口来创建多线程,Runnable接口不能返回结果,如果要获取子线程的执行结果,一般都是在子线程执行结束之后,通过Handler将结果返回到调用线程,jdk1.5之后,Java提供了Callable接口来封装子任务,Callable接口可以获取返回结果。
FutureTask + Thread
public class Test {
public static void main(String[] args) {
FutureTask<Integer> firstTask = new FutureTask<>(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
return 1;
}
});
FutureTask<Integer> secondTask = new FutureTask<>(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
return 2;
}
});
// FutureTask有Runnable接口和Callable接口的特征,可以被Thread执行。
new Thread(firstTask).start();
new Thread(secondTask).start();
try {
Integer one = firstTask.get();
Integer two = secondTask.get();
System.out.println(one); // 1
System.out.println(two);// 2
}catch (Exception e){
e.printStackTrace();
}
}
}
Future + ExecutorService
public class Test {
public static void main(String[] args) {
FutureTask<Integer> firstTask = new FutureTask<>(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
return 1;
}
});
FutureTask<Integer> secondTask = new FutureTask<>(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
return 2;
}
});
ExecutorService executorService = Executors.newCachedThreadPool();
executorService.submit(firstTask);
executorService.submit(secondTask);
executorService.shutdown();
try {
Integer one = firstTask.get();
Integer two = secondTask.get();
System.out.println(one); // 1
System.out.println(two);// 2
}catch (Exception e){
e.printStackTrace();
}
}
}
2.仿造futuretask核心原理,实现替换
package com.gpdi.operatingunit.test;
import java.util.concurrent.Callable;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.locks.LockSupport;
/**
* @description: 仿造futuretask核心原理,实现替换
* @author: Lxq
* @date: 2020/1/8 9:24
*/
public class DnFutureTask<T> implements Runnable {
// 线程集合
LinkedBlockingQueue<Thread> waiters = new LinkedBlockingQueue<>();
/**
* 封装业务逻辑的callable对象
*/
private Callable<T> callable;
/**
* 返回值
*/
T call;
String state = "new";
public DnFutureTask(Callable<T> callable) {
this.callable = callable;
}
/**
* 执行业务逻辑
*/
@Override
public void run() {
try {
call = callable.call();
} catch (Exception e) {
e.printStackTrace();
} finally {
state = "end";
}
while (true) {
Thread waiter = waiters.poll();
if (waiter == null) {
break;
}
LockSupport.unpark(waiter);
}
}
/**
* 获取执行结果
*/
public T get() {
Thread mainThread = Thread.currentThread();
waiters.add(mainThread);
// 判断是否执行完毕,如果执行完毕,则让当前调用get的方法的线程停一下,等待结果
if ("end".equals(state)) {
return call;
}
// 等待run执行结果
System.out.println(Thread.currentThread().getName() + "消费者即进入等待");
// park unpark 机制,挂起等待
LockSupport.park(mainThread);
return call;
}
}
测试:
public class Test {
public static void main(String[] args) {
DnFutureTask<Integer> firstTask = new DnFutureTask<>(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
return 1;
}
});
DnFutureTask<Integer> secondTask = new DnFutureTask<>(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
return 2;
}
});
new Thread(firstTask).start();
new Thread(secondTask).start();
try {
Integer one = firstTask.get();
Integer two = secondTask.get();
System.out.println(one); // 1
System.out.println(two);// 2
}catch (Exception e){
e.printStackTrace();
}
}
}