欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

java面试常问的Runnable和Callable的区别

程序员文章站 2022-03-01 20:57:27
runnablerunnable接口非常简单,就定义了一个方法run(), 实现runnable接口的run方法就可以实现多线程// 函数式接口@functionalinterfacepublic i...

runnable

runnable接口非常简单,就定义了一个方法run(), 实现runnable接口的run方法就可以实现多线程

// 函数式接口
@functionalinterface
public interface runnable {
    public abstract void run();
}

callable

可能很多人都知道要想在多线程中获取异步返回值结果一般是用callable和futuretask接口来实现,但可能很多人都不知道其实callable是依赖于runnable的run方法进行执行任务的,然后在通过futuretask来收集返回值结果,下面咱们就自己模拟写一份futuretask代码来看看是怎么实现的吧。

 /**
 * @author yinfeng
 * @description  自己实现futuretask,基于park/unpark进行线程通讯
 * @since 2022/1/9 21:32
 */
public class myfuturetask<t> implements runnable {
     callable<t> callable;
    /**
     * callable执行结果
     */
    t result;
    /**
     * task执行状态
     */
    string state = "new";
    /**
     * 存储正在等待的消费者
     */
    linkedblockingqueue<thread> waiters = new linkedblockingqueue<>();

    public myfuturetask(callable<t> callable) {
        this.callable = callable;
    }

    @override
    public void run() {
        try {
            result = callable.call();
        } catch (exception e) {
            e.printstacktrace();
        } finally {
            state = "end";
        }

        // 任务执行完成后通过unpark通知消费者
        system.out.println(thread.currentthread().getname() + " 生产者执行结束,通知消费者");
        while (true) {
            thread waiter = waiters.poll();
            if (waiter == null) {
                break;
            }
            locksupport.unpark(waiter);
        }
    }

    /**
     * park / unpark
     */
    public t get() throws exception {
        thread mainthread = thread.currentthread();
        // 塞入等待的集合中
        waiters.add(mainthread); 
        // 判断状态
        system.out.println(thread.currentthread().getname() + " 消费者进入等待");
        while (!"end".equals(state)) {
        	// 阻塞等待任务执行完成后通知
            locksupport.park(mainthread);
        }
        return result;
    }
}
我们写个demo测试一下
/**
 * @author yinfeng
 * @description
 * @since 2022/1/9 21:32
 */
public class futuretasktest {
    public static void main(string[] args) throws exception {
        final myfuturetask<string> futuretask = new myfuturetask<>(() -> {
            thread.sleep(5000);
            return "任务完成888";
        });
        new thread(futuretask).start();
        final string result = futuretask.get();
        system.out.println("结果:"+result);
        // 控制台打印如下: 
        // main 消费者进入等待
		// thread-0 生产者执行结束,通知消费者
		// 结果:任务完成888
    }
}
可以看到我们的demo也是正常运行的,所以很关键的一点还是callable是依赖于runnable的run方法进行执行任务的

到此这篇关于java面试常问的runnable和callable的区别的文章就介绍到这了,更多相关java runnable和callable区别内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!