• 温故知新----线程之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)
    
  • 相关阅读:
    NIO的浅了解
    ubuntu16.04上安装gstreamer
    代码随想录-day2
    nodejs基于微信小程序的书籍销售系统--(ssm+uinapp+Mysql)
    资源描述框架的用途及实际应用解析
    线扫相机设置编码器触发
    开源汇智创未来 | 2022开放原子全球开源峰会OpenAtom openEuler分论坛圆满召开
    【电路笔记】-串联RLC电路分析
    富文本文案存储翻译方案
    你对java的原子性了解多少?
  • 原文地址:https://www.cnblogs.com/jinliang374003909/p/17261669.html