• 温故知新----线程之Runnable与Callable接口的本质区别


    温故知新----线程之Runnable与Callable接口的本质区别

    预备知识:Java中的线程对象是Thread,新建线程也只有通过创建Thread对象的实例来创建。

    先说结论

    1 Runnable没有返回值的FunctionalInterface(jdk 1.8概念)接口,相反Callable是有返回值的FunctionalInterface接口

    2 Runnable + Thread 创建一个无返回结果的任务线程

    3 Runnable + Callable +Thread 创建一个有返回结果的任务线程

    一:Runnable 示例

    ​ 创建一个无返回结果的任务线程,so eazy !!!!

    public static void main(String[] args) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName() + "我是一个无返回结果的任务线程");
                }
            },"线程一:").start(); //start()开启任务
        }
    

    二:Callable示例

    2.1 JAVA异步编程之Callbacks与Futures模型 我是用Executors线程池的方式来创建的。

    2.2 用最原始的方法

    public class PrimitiveCallable implements Callable, Runnable {
        
        public static void main(String[] args) {
            //实现
            new Thread(new PrimitiveCallable(), "线程二:").start();
        }
        @Override
        public void run() {//Runnable实现
            try {
                Object call = this.call();
                System.out.println(call);
            } catch (Exception exception) {
                exception.printStackTrace();
            }
        }
        @Override
        public Object call() throws Exception { //Callable 实现
            return "异步任务返回的结果!!!";
        }
    }
    

    2.3 FutureTask 一种jdk的实现方式

    public class FutureTask implements RunnableFuture { //RunnableFuture 实现了以上2个接口
        ........省略.........
    	public void run() { //重写run实现
            if (state != NEW ||
                !UNSAFE.compareAndSwapObject(this, runnerOffset,
                                             null, Thread.currentThread()))
                return;
            try {
                Callable c = callable; //构建对象是传入的参数
                if (c != null && state == NEW) {
                    V result;
                    boolean ran;
                    try {
                        result = c.call(); //调用任务并返回结果
                        ran = true;
                    } catch (Throwable ex) {
                        result = null;
                        ran = false;
                        setException(ex); //设置异常时的结果
                    }
                    if (ran)
                        set(result); //设置结果
                }
            } finally {
                runner = null;
                int s = state;
                if (s >= INTERRUPTING)
                    handlePossibleCancellationInterrupt(s);
            }
        }
         ........省略.........
    }
    

    小结

    1 不要纠结有几种创建线程的方法了,就一种即通过Thread,但Thread有9个构造函数方法

    2 9个构造函数方法

    1 public Thread()
    2 public Thread(Runnable target)
    3 Thread(Runnable target, AccessControlContext acc)
    4 public Thread(ThreadGroup group, Runnable target)
    5 public Thread(String name)
    6 public Thread(ThreadGroup group, String name)
    7 public Thread(Runnable target, String name)
    8 public Thread(ThreadGroup group, Runnable target, String name)
    9 public Thread(ThreadGroup group, Runnable target, String name,
                      long stackSize)
    
  • 相关阅读:
    VMWare workstation虚拟机 转kvm qemu 的Qcow2格式
    【质量】代码质量评价标准
    Python实战 | 使用 Python 的日志库(logging)和 pandas 库对日志数据进行分析
    代码随想录二刷day42
    啦啦外卖v60.5系统独立版+平台用户端+骑手端+商家端小程序 安装配置使用教程
    HDMI之HDCP 2.3
    35 | OpenResty:更灵活的Web服务器
    秒懂双亲委派机制
    1:引文;
    使用iCloud和Shortcuts实现跨设备同步与自动化数据采集
  • 原文地址:https://www.cnblogs.com/jinliang374003909/p/17261669.html