浅析多线程不同的接口实现:Callable、Runnable

Callable

接口

public interface Callable<V> {
        V call() throws Exception;
}

测试类

package com.hanbin.mybatisdemo.thread;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

/**
 * @author hanbin.jiang
 * @version 1.0.0
 * @ClassName CallableTest.java
 * @createTime 2022年06月17日 19:37:00
 * @Description TODO
 */
public class CallableTest implements Callable<String> {
    private String string;
    public CallableTest(String string) {
        this.string = string;
    }

    @Override
    public String call() throws Exception {
        //任务阻塞5秒,异常向上抛出
        Thread.sleep(5000);
        return this.string;
    }
//    异常也可以try catch解决
//    @Override
//    public String call(){
//        //任务阻塞5秒  异常向上抛出
//        try {
//            Thread.sleep(5000);
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }
//        return this.string;
//    }


    public static void main(String[] args) throws ExecutionException, InterruptedException {
        Callable<String> callable = new CallableTest("my callable is ok!");
        FutureTask<String> task = new FutureTask<String>(callable);
        long beginTime = System.currentTimeMillis();
        //创建线程
        new Thread(task).start();
        //调用get()方法阻塞主线程
        String str = task.get();
        long endTime = System.currentTimeMillis();
        System.out.println("hello :"+ str);
        System.out.println("time :"+ (endTime - beginTime)/1000);
    }

}


测试输出:间隔五秒之后输出
callable测试结果输出

Runnable

接口

public interface Runnable {
        void run();
}

测试类

package com.hanbin.mybatisdemo.thread;

/**
 * @author hanbin.jiang
 * @version 1.0.0
 * @ClassName RunnableTest.java
 * @createTime 2022年06月17日 19:41:00
 * @Description TODO
 */
public class RunnableTest implements Runnable{
    private String str;

    public RunnableTest(String str) {
        this.str = str;
    }
    @Override
    public void run() {
        try {
            //线程休眠5s,有异常产生,只能内部解决,无法向上抛
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //5s之后输出
        System.out.println("hello:" + this.str);
    }
    public static void main(String[] args) {
        Runnable runnable = new RunnableTest("my runnable is ok");
        Long beginTime = System.currentTimeMillis();
        Thread thread=new Thread(()->{
            runnable.run();
        });
        thread.start();
        Long endTime = System.currentTimeMillis();
        //先输出
        System.out.println("time:" + (endTime-beginTime)/1000);
    }
}

测试结果:

runnable接口测试结果输出

两者的区别

1、最大的区别,runnable没有返回值,而实现callable接口的任务线程能返回执行结果
2、callable接口实现类中的run方法允许异常向上抛出,可以在内部处理,try catch,但是runnable接口实现类中run方法的异常必须在内部处理,不能抛出

补充Executor框架

Executor框架是由任务任务的执行异步计算的结果组成

  1. Executor是一个接口,它是Executor框架的基础,它将任务的提交与任务的执行分离开来;
  2. ThreadPoolExecutor是线程池的核心实现类,用来执行被提交的任务;
  3. ScheduledThreadPoolExecutor是一个实现类,可以在给定的延迟后运行命令,或者定期执行命令。ScheduledThreadPoolExecutor比Timer更灵活,功能更强大;
  4. Future接口和实现Future接口的FutureTask类,代表异步计算的结果;
  5. Runnable接口和Callable接口的实现类,都可以被ThreadPoolExecutor或Scheduled-ThreadPoolExecutor执行;

框架使用示意图
框架示意图

框架使用解释:

主线程首先要创建实现Runnable或者Callable接口的任务对象。工具类Executors可以把一
个Runnable对象封装为一个Callable对象(Executors.callable(Runnable task)或 Executors.callable(Runnable task,Object resule))。
然后可以把Runnable对象直接交给ExecutorService执行(ExecutorService.execute(Runnable command));或者也可以把Runnable对象或Callable对象提交给ExecutorService执行(ExecutorService.submit(Runnable task)或ExecutorService.submit(Callabletask))。
如果执行ExecutorService.submit(…),ExecutorService将返回一个实现Future接口的对象(到目前为止的JDK中,返回的是FutureTask对象)。由于FutureTask实现了Runnable,我们也可以创建FutureTask,然后直接交给ExecutorService执行。
最后,主线程可以执行FutureTask.get()方法来等待任务执行完成。主线程也可以执行 FutureTask.cancel(boolean mayInterruptIfRunning)来取消此任务的执行。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值