手写一个callable创建线程,来了解下原理

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();

来实现

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值