1.先模拟源码的Callable创建自己的MyCallable
package com.example.test.demo.thread.callable;
/**
* @author 王健宇
* @title: MyCallable
* @description
* @date 2021/7/9 19:12
*/
public interface MyCallable<T> {
T call();
}
2.创建自己的FutureTask
package com.example.test.demo.thread.callable;
/**
* 因为要放在Thread中执行,所以要实现Runnable
* @author 王健宇
* @title: MyFutrueTask
* @description
* @date 2021/7/9 19:13
*/
public class MyFutureTask<T> implements Runnable{
final Object object = new Object();
private T result;
private MyCallable<T> callable;
public MyFutureTask(MyCallable<T> callable) {
this.callable = callable;
}
@Override
public void run() {
result = callable.call();
// 线程执行完,换新get()方法中等待的线程
// wait要放在synchronized
synchronized (object) {
object.notify();
}
}
/**
* 获取多线程返回值
* @return 返回多线程执行结果
*/
public T get () throws InterruptedException {
// 必须等线程执行完才能返回
// wait要放在synchronized
synchronized (object) {
object.wait();
return result;
}
}
}
3.最后测试
package com.example.test.demo.thread.callable;
import com.example.test.pojo.User;
import java.util.Date;
/**
* @author 王健宇
* @title: MyCallableDemo
* @description
* @date 2021/7/9 19:14
*/
public class MyCallableDemo {
public static void main(String[] args) throws InterruptedException {
// 1. 创建callable
MyCallable<User> callable = new MyCallable<User>() {
@Override
public User call() {
// 模拟执行耗时 3秒
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return new User("用户" + new Date().getTime(), "29");
}
};
// 2.创建futureTask
MyFutureTask<User> future = new MyFutureTask<>(callable);
// 3.放到线程中执行
new Thread(future).start();
// 4.获取返回结果
User user = future.get();
// 5.打印
System.out.println(user);
}
}
4.最后,这里是用wait和notify模拟的,还可以使用
LockSupport.park();
LockSupport.unpark();
来实现