zoukankan      html  css  js  c++  java
  • Java Runnable与Callable区别

    接口定义

    #Callable接口

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

    #Runnable接口

    public interface Runnable {
        public abstract void run();
    }

    相同点

    都是接口

    都可以编写多线程程序

    都采用Thread.start()启动线程

    不同点

    Runnable没有返回值;Callable可以返回执行结果,是个泛型,和Future、FutureTask配合可以用来获取异步执行的结果

    Callable接口的call()方法允许抛出异常;Runnable的run()方法异常只能在内部消化,不能往上继续抛

    :Callalble接口支持返回执行结果,需要调用FutureTask.get()得到,此方法会阻塞主进程的继续往下执行,如果不调用不会阻塞。

    示例

    #Callable-1

    import java.util.Random;
    import java.util.concurrent.Callable;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.FutureTask;
    
    public class CallableAndFuture {
        public static void main(String[] args) {
            Callable<Integer> callable = new Callable<Integer>() {
                @Override
                public Integer call() throws Exception {
                    Thread.sleep(6000);
                    return new Random().nextInt();
                }
            };
            FutureTask<Integer> future = new FutureTask<>(callable);
            new Thread(future).start();
            try {
                Thread.sleep(1000);
                System.out.println("hello begin");
                System.out.println(future.isDone());
                System.out.println(future.get());
                System.out.println(future.isDone());
                System.out.println("hello end");
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
        }
    }

    结果

    hello begin
    false
    1664014921
    true
    hello end

    #Callable-2

    import java.util.concurrent.Callable;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.FutureTask;
    
    public class CallableThreadTest implements Callable<Integer> {
        public static void main(String[] args) throws ExecutionException, InterruptedException {
            CallableThreadTest ctt = new CallableThreadTest();
            FutureTask<Integer> ft = new FutureTask<>(ctt);
            new Thread(ft, "有返回值的线程").start();
            System.out.println("子线程的返回值" + ft.get());
        }
    
        @Override
        public Integer call() {
            int i;
            for (i = 0; i < 10; i += 2) {
                System.out.println(Thread.currentThread().getName() + " " + i);
            }
            return i;
        }
    }

    结果

    有返回值的线程 0
    有返回值的线程 2
    有返回值的线程 4
    有返回值的线程 6
    有返回值的线程 8
    子线程的返回值10

    优势

    多线程返回执行结果是很有用的一个特性,因为多线程相比单线程更难、更复杂的一个重要原因就是因为多线程充满着未知性,某条线程是否执行了?某条线程执行了多久?某条线程执行的时候我们期望的数据是否已经赋值完毕?无法得知,我们能做的只是等待这条多线程的任务执行完毕而已。而Callable+Future/FutureTask却可以获取多线程运行的结果,可以在等待时间太长没获取到需要的数据的情况下取消该线程的任务,真的是非常有用。

    public class CallableAndFuture {
        public static void main(String[] args) {
            Callable<Integer> callable = new Callable<Integer>() {
                @Override
                public Integer call() throws Exception {
                    Thread.sleep(6000);
                    return new Random().nextInt();
                }
            };
            FutureTask<Integer> future = new FutureTask<>(callable);
            new Thread(future).start();
            try {
                Thread.sleep(1000);
                System.out.println("hello begin");
                System.out.println(future.isDone());
    //            future.cancel(false);
                if (!future.isCancelled()) {
                    System.out.println(future.get());
                    System.out.println(future.isDone());
                    System.out.println("hello end");
                } else {
                    System.out.println("cancel~");
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
        }
    }
  • 相关阅读:
    window.loaction.href 不自动跳转的问题
    SQL语句
    C# 里面swith的或者
    跨域
    memcached总结
    应用 memcached 提升站点性能
    安装和使用 memcached
    Unity3D学习笔记(三十):Lua
    Unity3D学习笔记(二十九):AssetBundle
    Unity3D学习笔记(二十八):Editor
  • 原文地址:https://www.cnblogs.com/kaituorensheng/p/9502968.html
Copyright © 2011-2022 走看看