精华内容
下载资源
问答
  • 使用callable开启线程
    2020-06-19 18:13:20

    //
    在学校中常用的方式是:

    class Test {
    	public static void main(String[] args) {
    	    Thread t = new Thread(MyThread, "A");
    	    t.start();
    	}
    }
    class MyThread implements Runnable {
    	public void run() {
    		System.out.println("实现Runnable");
    	}
    }
    

    如果学了lambda表达式后主函数可以改的更加优雅:

    new Thread(() -> System.out.println("实现Runnable"), "A").start();
    

    使用闭包的条件是接口中只有一个待实现的方法。

    通过实现Runable接口开启线程的不足就是没有返回值。Callable接口可以解决这个问题。

    public static void main(String[] args) {
    	FutureTask<Integer> futureTask = new FutureTask<>(() -> {
    	    System.out.println("调用callable实现类");
    	    return 1;
    	});
    	new Thread(futureTask, "A").start();
    	new Thread(futureTask, "B").start();
    
    	Integer i = futureTask.get();
        System.out.println(i);
    }
    

    这里的FutureTask实现了Callable
    上述代码的结果打印出一个"调用callable实现类"。
    这是由于FutureTask在内部还维护了一个state,表示线程的状态:
    NEW=0、COMPLETING=1、NORMAL=2、EXCEPTIONAL=3、CANCELLED=4、INTERRUPTING=5、INTERRUPTED=6
    同一个futureTask只会在初始化线程的时候state = NEW,在线程正常结束后会将state置为NOMAL,所以当启动新线程时futureTask的state为NOMAL,直接退出线程。
    此外,get方法可以得到futureTask的返回值,但是判断条件是state>COMPLETING,所以线程未执行完就会等待,造成主线程的阻塞。这里可以用异步通信解决。

    更多相关内容
  • 初学python,很容易犯这样的错误,即直接用set, list, tuple, dict, str, int, complex, float等作为变量名。这样会导致这些内置函数:set(), list(), tuple()等等无法执行。 例如下例,使用tuple作为变量名,再执行...
  • Java执行Callable任务

    2020-07-08 14:54:23
    文章目录一、引言二、使用线程运行 Callable 任务得到返回结果2.1 不能直接运行2.2 Future 接口2.3 RunnableFuture 接口2.4 FutureTask 类2.5 示例: FutureTask + Thread 执行Callable任务三、使用线程池运行 ...

    一、引言

    • JDK1.0的 Thread 和 Runnable 线程,run()方法返回void,在线程执行完后无法返回执行结果;
    • JDK1.5 引入 Callable 接口,如同Runnable接口,该接口也只有一个方法 call(), 但是,该方法可以有返回结果,也可以抛出异常.
    // Runnable 接口源码
    public interface Runnable {
        public abstract void run();
    }
    
    
    // Callable 接口源码
    public interface Callable<V> {
        V call() throws Exception;
    }
    

    区别:

    • Callable 接口可以返回值,返回类型由泛型表示
    • Callable 接口可以抛出异常
    • Callable 对象不能直接传递给 Thread类运行

    二、使用线程运行 Callable 任务得到返回结果

    2.1 不能直接运行

    • Callable 对象不能直接传递给Thread类运行,因为Thread的构造方法只接收Runnable接口对象;
    • Callable 对象更不能直接调用start方法运行,只有Thread对象才能直接调用start方法运行;
    • Callable 对象直接调用 call方法是执行方法而不是开启线程,就像Thread对象(Runnable对象)直接执行run方法一样;
    // Thread 类的构造方法
    public Thread() {}
    public Thread(Runnable target) {}
    Thread(Runnable target, AccessControlContext acc) {}
    public Thread(ThreadGroup group, Runnable target) {}
    public Thread(String name) {}
    public Thread(ThreadGroup group, String name) {}
    public Thread(Runnable target, String name) {}
    public Thread(ThreadGroup group, Runnable target, String name) {}
    public Thread(ThreadGroup group, Runnable target, String name,
                      long stackSize) {}
    
    |--->Ruunable (interface)
    |
    |--->Future<V> (interface)
    |   |
    |   |
    |---|-> RuunableFutur (interface)
                |
                |---> FutureTask (class)
                
    

    2.2 Future 接口

    • Future 接口用来获取异步执行结果
    // Future 接口源码
    public interface Future<V> {
    
        boolean cancel(boolean mayInterruptIfRunning);
    
        boolean isCancelled();
    
        boolean isDone();
    
        V get() throws InterruptedException, ExecutionException;
    
        V get(long timeout, TimeUnit unit)
            throws InterruptedException, ExecutionException, TimeoutException;
    }
    

    方法:

    • get() 方法会产生阻塞,直到任务执行完毕返回结果;
    • get(long timeout, TimeUnit unit) 方法阻塞获取执行结果,但是会限制等待时间,等待超时后,会直接返回null;
    • isDone() 方法判断任务是否执行完成,完成返回true;
    • cancel() 方法用来取消任务,如果任务未开始执行,则会取消成功返回true,如果任务已经执行完成,则取消失败返回false,如果任务正在运行中,则根据参数 mayInterruptIfRunning 决定是否取消正在执行中的任务,如果取消则取消成功,如果不取消执行中的任务,则取消失败。如100-图1 所示。
    • isCancelled() 方法判断任务是否被取消成功

    2.3 RunnableFuture 接口

    • RunnableFuture 接口同时继承了 Runnable接口和Future 接口,由于继承了Runnable接口,所以该接口的对象可以传递给Thread类执行
    // RunnableFuture 接口源码
    public interface RunnableFuture<V> extends Runnable, Future<V> {
        void run();
    }
    

    2.4 FutureTask 类

    • FutureTask 类实现了RunnableFuture接口,类有run方法,也有get方法

    注意:

    • Thread 类是实现了 Runnable 接口的;
    • 但是,不管FutureTask类还是Future接口,都没有继承或实现 Callable接口;

    那么该怎么运行Callable任务呢?

    • 答案在FutureTask类的构造方法里
    public class FutureTask<V> implements RunnableFuture<V> {
    
        public FutureTask(Callable<V> callable) {}
        public FutureTask(Runnable runnable, V result) {}
    }
    

    构造方法

    • FutureTask 类有两构造方法:一个接收Callable对象,一个接收 Runnable对象
    • 接收Callable对象后,将Callable 任务的 call方法返回的结果封装进来,通过get方法获取;
    • 接收Runnable对象后,将第二个参数 result的结果在执行完毕后封装进来,通过get方法获取;
    • 由于同时继承了Runnable接口和Future接口,所以FutureTask对象既可以作为Runnable被线程执行,有可以作为Future得到Callable的返回值

    2.5 示例: FutureTask + Thread 执行Callable任务

    • Callable 任务
    public class CallableTask implements Callable<Integer> {
        @Override
        public Integer call() throws Exception {
            Integer sum = 0;
            for (int i = 0; i < 10; i++) {
                sum += i;
                System.out.println("ThreadName:" + Thread.currentThread().getName() + " i=" + i);
                Thread.sleep(20);
            }
            return sum;
        }
    }
    
    • 使用Thread执行 FutureTask
    /**
     * 方法一:使用 FutureTask 执行callable
     *
     * @param callableTask
     */
    public static void methodA(CallableTask callableTask) {
        FutureTask<Integer> futureTask = new FutureTask(callableTask);
        Thread thread = new Thread(futureTask);
        thread.start();
        try {
            System.out.println("ThreadName:" + Thread.currentThread().getName() + " Time:" + System.currentTimeMillis());
            // 阻塞方法,等待返回结果
            Integer result = futureTask.get();
            System.out.println("ThreadName:" + Thread.currentThread().getName() + " Time:" + System.currentTimeMillis());
            System.out.println("result=" + result);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }
    
    • 执行结果
    ThreadName:main Time:1569812722242
    ThreadName:Thread-0 i=0
    ThreadName:Thread-0 i=1
    ThreadName:Thread-0 i=2
    ThreadName:Thread-0 i=3
    ThreadName:Thread-0 i=4
    ThreadName:Thread-0 i=5
    ThreadName:Thread-0 i=6
    ThreadName:Thread-0 i=7
    ThreadName:Thread-0 i=8
    ThreadName:Thread-0 i=9
    ThreadName:main Time:1569812722456
    result=45
    

    三、使用线程池运行 Callable 任务得到返回结果

    3.1 Excutors类

    • JDK1.5 使用Excutors提供四种线程池(后边会详细讲解)
    • Excutors 创建的线程池返回类型就是ExcutorService
    • ExcutorService是一个接口,是一个由JDK提供的框架,它简化了异步模式运行task的工作,简单来说,ExcutorService会自动提供一个线程池,以及常用的API
    // Excutors 几个创建线程池的方法
    
    // 1. 可缓存线程池
    public static ExecutorService newCachedThreadPool() {
        // 当然有重载的带参数的方法,这里不详细列举
    }
    
    // 2.定长线程池
    public static ExecutorService newFixedThreadPool(int nThreads) {
        // 当然有重载的其他带参数的方法,这里不详细列举
    }
    
    // 3. 定长线程池,支持定时及周期性任务执行
    public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
        // 当然有重载的其他带参数的方法,这里不详细列举
    }
    
    // 4. 单线程化的线程池
    public static ExecutorService newSingleThreadExecutor() {
        // 当然有重载的其他带参数的方法,这里不详细列举
    }
    
    

    3.2 ExcutorService 接口

    • ExcutorService 是一个接口,具体的实例看Excutors实例化的线程池类型
    • ExcutorService 接口封装了常用的工作管理方法
    // 关闭线程池
    void shutdown();
    // 开始执行任务,异步结果放入 Future 对象里
    <T> Future<T> submit(Callable<T> task);
    <T> Future<T> submit(Runnable task, T result);
    Future<?> submit(Runnable task);
    
    • ExcutorService 既可以执行 Callable任务,也可以执行 Runnable任务
    • 如果执行的任务不需要等待返回值,则调用execute方法(从Executor接口继承的)
    • 如果执行的任务需要等待返回结果,则调用submit方法,返回结果封装到Future对象中

    3.3 示例:Future + ExcutorService 执行 Callable任务

    • Callable任务如上
    • 使用ExcutorService 执行 Callable
    /**
     * 方式二:用线程池执行callable
     *
     * @param callableTask
     */
    public static void methodB(CallableTask callableTask) {
        // ==== 1. 第2种方式,用线程池执行
        // 创建线程池
        ExecutorService executorService = Executors.newCachedThreadPool();
        
        // 提交线程任务,结果封装到 future里
        // 需要等待异步返回结果的Callable任务和Runnable任务用submit提交,不需要等待结果的Runnable任务用execute提交
        Future<Integer> future = executorService.submit(callableTask);
        executorService.shutdown();     // 所有线程执行完后关闭线程池
    
        try {
            System.out.println("ThreadName:" + Thread.currentThread().getName() + " Time:" + System.currentTimeMillis());
            // 阻塞方法,等待返回结果
            Integer result = future.get();
            System.out.println("ThreadName:" + Thread.currentThread().getName() + " Time:" + System.currentTimeMillis());
            System.out.println("result=" + result);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }
    
    • 执行结果
    ThreadName:pool-1-thread-1 i=0
    ThreadName:main Time:1569817489464
    ThreadName:pool-1-thread-1 i=1
    ThreadName:pool-1-thread-1 i=2
    ThreadName:pool-1-thread-1 i=3
    ThreadName:pool-1-thread-1 i=4
    ThreadName:pool-1-thread-1 i=5
    ThreadName:pool-1-thread-1 i=6
    ThreadName:pool-1-thread-1 i=7
    ThreadName:pool-1-thread-1 i=8
    ThreadName:pool-1-thread-1 i=9
    ThreadName:main Time:1569817489678
    result=45
    
    展开全文
  • Callable线程如何一步步执行的

    千次阅读 2019-06-16 22:42:13
    2.1 使用Callable线程步骤: 3. 代码设计分析 4. 深入Callable具体源码,一步步查看如何执行: 4.1 Callbale接口---FutureTask构造方法的接口 4.2 FutureTask类和内部重要方法 4.3 RunnableFuture接口---继承了...

    目录

    1. 背景

    2. 案例: 

    2.1 使用Callable线程步骤:

    3. 代码设计分析

    4. 深入Callable具体源码,一步步查看如何执行:

    4.1 Callbale接口---FutureTask构造方法的接口

    4.2 FutureTask类和内部重要方法 

    4.3 RunnableFuture接口 ---继承了Runnable,Future接口

    4.4 Runnable接口 

    4.5 Future接口 

    5. 为了能站在全局的角度来看,所以画了一张流程图,感觉好丑。。。


    1. 背景

    我们知道线程的实现方式有4种

    1.继承Thread类

    2.实现Runnable接口

    3.实现Callable接口:与其他明显区别是有返回值。

    4.线程池

    本文讲述第三种的执行流程。

    刚开始感觉实现Callable接口的方法有点复杂,好奇内部到底是怎么实现的,就看了以下源码,发现代码不难,但是思路很巧妙。

    2. 案例: 

    MyThread类实现Callable接口,泛型是返回对象的类型,这里是Integer

    2.1 使用Callable线程步骤:

    1.定义一个MyThread,实现Callable接口

    2.重写call()方法:类似run()方法

    3.创建FutureTask对象,构造方法参数是MyThread对象。

    4.创建Thread对象,构造方法参数是MyThread对象。

    5.开启线程

    6.获取返回值,返回值保存在了FutureTask对象种,通过get()方法返回。

    代码如下:

    public class MyThread implements Callable<Integer>{
    
        @Override
        public Integer call() throws Exception {
            System.out.println("*************************");
            return 1024;
        }
    
        public static void main(String[] args)throws Exception{
            FutureTask<Integer> futureTask = new FutureTask<Integer>(new MyThread());
            Thread thread = new Thread(futureTask); 
            thread.start();  //开启线程
            Integer result = futureTask.get();   //获取返回值
            System.out.println("result is ****"+result);  //打印
        }
    
    }

    测试结果: 

    3. 代码设计分析

    我们知道Thread的构造方法参数是Runnable接口,也就是new Thread(new Runnable())这种形式,但是我们的MyThread类没有实现Runnable接口,但是RunnableFuture继承了Runnable接口,而FutureTask又实现了Runnable,所以FutureTask可以向上转型为Runnable,并作为Thread构造方法参数传入。而Callable接口的call()方法又是如何与Runnable方法联系起来的的呢?答案是:Callable的实现类MyThread作为FutureTask(相当于Runnable)的构造方法的传入参数,而Runnable的run()方法内会调用call()方法,所以就联系起来了。

    总结一下执行大体流程:

    thread:start()====>thread:run()====>MyThread():call()====>FutureTask:set(result)====>FutureTask:report()====>FutureTask:get()方法返回result

    4. 深入Callable相关具体源码,只贴重要的部分

    代码是按顺序贴的,为了思路更加清楚,贴一下自己画的流程图(和后面的一张是一样的,这里放到前面了),有点丑,不想看的忽略。。。

    4.1 Callbale接口---FutureTask构造方法的接口

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

    4.2 FutureTask类和内部重要方法 

    该类实现了RunnableFuture接口(而该接口又实现了Runnable接口,所以FutureTask可以作为Thread构造函数的参数向上转型为Runnable,这里面包含一种重要思想--运行时多态或者说时动态绑定,好处是对外提供统一接口,但是具体实现类却千变万化,妙呀!)

    public class FutureTask<V> implements RunnableFuture<V> {
        
        //构造函数
        public FutureTask(Callable<V> callable) {
            if (callable == null)
                throw new NullPointerException();
            this.callable = callable;
            this.state = NEW;       
        }
    
        //run方法
        //关键代码:
        //1.result = c.call(),可以看到run方法调用了call()方法
        //2.set(result),可以看到运行结果通过set方法保存
        public void run() {
            if (state != NEW ||
                !UNSAFE.compareAndSwapObject(this, runnerOffset,
                                             null, Thread.currentThread()))
                return;
            try {
                Callable<V> 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);
            }
        }
        
        //get方法
        //调用report方法返回结果,具体看report方法
        public V get() throws InterruptedException, ExecutionException {
            int s = state;
            if (s <= COMPLETING)
                s = awaitDone(false, 0L);
            return report(s);
        }
    
        //set方法
        //关键代码:
        //outcome = v;可以看到,结果包存到了outcome中
        protected void set(V v) {
            if (UNSAFE.compareAndSwapInt(this, stateOffset, NEW, COMPLETING)) {
                outcome = v;
                UNSAFE.putOrderedInt(this, stateOffset, NORMAL); // final state
                finishCompletion();
            }
        }
    
        //report方法
        //关键代码:
        //Object x = outcome,return (V)x;可以看到,结果outcome赋给x然后返回了
        private V report(int s) throws ExecutionException {
            Object x = outcome;
            if (s == NORMAL)
                return (V)x;
            if (s >= CANCELLED)
                throw new CancellationException();
            throw new ExecutionException((Throwable)x);
        }
    }

    4.3 RunnableFuture接口 ---继承了Runnable,Future接口

    public interface RunnableFuture<V> extends Runnable, Future<V> {
        
        void run();
    }

    4.4 Runnable接口 

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

    4.5 Future接口 

    public interface Future<V> {
    
        boolean cancel(boolean mayInterruptIfRunning);
    
        boolean isCancelled();
       
        boolean isDone();
      
        V get() throws InterruptedException, ExecutionException;
       
        V get(long timeout, TimeUnit unit)
            throws InterruptedException, ExecutionException, TimeoutException;
    }
    

    5. 为了能站在全局的角度来看,画了一张流程图。

    感觉好丑。。。可能只有我自己能看懂。。。

    展开全文
  • Callable

    2021-08-18 00:54:48
    面试中或许都遇到过这样的问题:“Java中创建线程的方式有哪些?”,本篇文章要说的Callable接口就是其中一种。

    面试中或许都遇到过这样的问题:“Java中创建线程的方式有哪些?”,本篇文章要说的Callable接口就是其中一种。

    该部分内容,在我之前的文章《Java中线程创建方式》中也有部分提及,这里主要通过实例来只管说明,直接看实例也挺不错,简明易懂。

    因为该接口简单明了,这里直接附上源码。

    一、源码

    package java.util.concurrent;
    
    /**
     * A task that returns a result and may throw an exception.
     * Implementors define a single method with no arguments called
     * {@code call}.
     *
     * <p>The {@code Callable} interface is similar to {@link
     * java.lang.Runnable}, in that both are designed for classes whose
     * instances are potentially executed by another thread.  A
     * {@code Runnable}, however, does not return a result and cannot
     * throw a checked exception.
     *
     * <p>The {@link Executors} class contains utility methods to
     * convert from other common forms to {@code Callable} classes.
     *
     * @see Executor
     * @since 1.5
     * @author Doug Lea
     * @param <V> the result type of method {@code call}
     */
    @FunctionalInterface
    public interface Callable<V> {
        /**
         * Computes a result, or throws an exception if unable to do so.
         *
         * @return computed result
         * @throws Exception if unable to compute a result
         */
        V call() throws Exception;
    }
    

    简单介绍:
      返回结果并可能引发异常的任务。实现者定义了一个没有参数的方法call。
      Callable接口类似于Runnable,因为它们都是为那些实例可能由另一个线程执行的类设计的。然而,Runnable不会返回结果,也不会抛出检查异常。
      Executors类包含将其他通用形式转换为可调用类的实用程序方法。

    二、创建步骤

    (1)创建Callable接口的实现类,并实现call()方法,然后创建该实现类的实例(从java8开始可以直接使用Lambda表达式创建Callable对象)。
    (2)使用FutureTask类来包装Callable对象,该FutureTask对象封装了Callable对象的call()方法的返回值
    (3)使用FutureTask对象作为Thread对象的target创建并启动线程(因为FutureTask实现了Runnable接口)
    (4)调用FutureTask对象的get()方法来获得子线程执行结束后的返回值

    三、实例

    实例一:正常创建

    import java.util.concurrent.Callable;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.FutureTask;
    
    public class ThreadTest implements Callable<String> {
        private int count = 20;
        @Override
        public String call() {
            for (int i = count; i > 0; i--) {
                System.out.println(Thread.currentThread().getName()+"当前数目:" + i);
            }
            return "Game over!!!";
        }
        public static void main(String[] args) throws InterruptedException, ExecutionException {
            Callable<String> callable  =new ThreadTest();
            FutureTask <String>futureTask=new FutureTask<>(callable);
            Thread mThread=new Thread(futureTask);
            mThread.start();
            System.out.println(futureTask.get());
        }
    }
    

    实例二:Lambda表达式创建

    import java.util.concurrent.Callable;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.FutureTask;
    
    public class ThreadTest implements Callable<String> {
        private int count = 20;
        @Override
        public String call() {
            for (int i = count; i > 0; i--) {
                System.out.println(Thread.currentThread().getName()+"当前数目:" + i);
            }
            return "Game over!!!";
        }
        public static void main(String[] args) throws InterruptedException, ExecutionException {
            Callable<String> callable  =new ThreadTest();
            FutureTask <String>futureTask=new FutureTask(() -> callable.call());
            new Thread(futureTask,"ThreadName").start();
            System.out.println(futureTask.get());
        }
    }
    

    实例一和二的运行结果如下,区别是实例二自定义了一个线程名称:

    ThreadName当前数目:20
    ThreadName当前数目:19
    ThreadName当前数目:18
    ThreadName当前数目:17
    ThreadName当前数目:16
    ThreadName当前数目:15
    ThreadName当前数目:14
    ThreadName当前数目:13
    ThreadName当前数目:12
    ThreadName当前数目:11
    ThreadName当前数目:10
    ThreadName当前数目:9
    ThreadName当前数目:8
    ThreadName当前数目:7
    ThreadName当前数目:6
    ThreadName当前数目:5
    ThreadName当前数目:4
    ThreadName当前数目:3
    ThreadName当前数目:2
    ThreadName当前数目:1
    Game over!!!
    

    实例三:多线程状态(这里用两个线程为例)

    import java.util.concurrent.Callable;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.FutureTask;
    import java.util.concurrent.atomic.AtomicInteger;
    
    public class ThreadTest implements Callable<String> {
        AtomicInteger count = new AtomicInteger(10000);
        private int count0 = 0;
    
        public String call() {
            while (count.get() > 0){
                System.out.println(Thread.currentThread().getName()+"当前数目:" + count.getAndDecrement());
                System.out.println(++count0);
            }
            return "Game over!!!";
        }
        public static void main(String[] args) {
            Callable<String> callable  =new ThreadTest();
            FutureTask<String> feature1 = new FutureTask(()-> callable.call());
            FutureTask<String> feature2 = new FutureTask(()-> callable.call());
            new Thread(feature1,"######ThreadName1").start();
            new Thread(feature2,"######ThreadName2").start();
            try {
                System.out.println("子线程1的返回值:" + feature1.get());
                System.out.println("子线程2的返回值:" + feature1.get());
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
        }
    }
    

    为方便观察,这里定义了一个原子数10000,结果是原子递减的。

    四、优劣

    (1)优势:
      线程类只是实现了Runnable接口或Callable接口,还可以继承其他类。在这种方式下,多个线程可以共享同一个target对象,适合多个相同线程来处理同一份资源的情况。
    (2)劣势:
      编程稍微复杂,如果要访问当前线程,则必须使用Thread.currentThread()方法。

    注:一般推荐采用实现接口的方式来创建多线程

    展开全文
  • Callable是可以获取返回值的Runnable,不过Callable只能通过线程池,来直接的提交任务。 如果通过Runnable来执行任务,则只能通过FutureTask来获取返回值。 线程池ExecutoerService的execute()方法,只接收...
  • Callable实现多线程 从最传统来讲如果要进行多线程的实现肯定要依靠的就是Runnable,但是Runnable接口有一个缺点:当线程执行完毕之后无法获取一个返回值,所以从JDK1.5之后就提出了一个新的线程实现接口:java.util...
  • 在Java 1.5以前,创建线程的2种方式,一种是直接继承Thread,另外一种就是实现Runnable接口。无论我们以怎样的形式实现多线程,都需要调用Thread类中的start方法去向操作系统请求io,cup等资源。因为线程run方法没有...
  • 高并发之——深入解析Callable接口

    千次阅读 2020-02-17 14:58:52
    本文纯干货,从源码角度深入解析Callable接口,希望大家踏下心来,打开你的IDE,跟着文章看源码,相信你一定收获不小。 1.Callable接口介绍 Callable接口是JDK1.5新增的泛型接口,在JDK1.8中,被声明为函数式接口...
  • 1 Callable 接口 接口内部仅有一个call()方法,方法返回类型为接口泛型定义的类型。实现类重写内部方法后,通过Future接口的包装类进行包装,来实现Runable接口,从而能够开启新的线程。与Runable不同的是:...
  • 为了支持此功能,Java中提供了Callable接口。 当然了还可以使用线程池创建线程。 Callable接口和Runnable接口的区别 Callable接口中定义了需要有返回的任务需要实现的call方法。 比如主线程让一个子线程去执行任务,...
  • 后面测试了一下最简单的程序,发现是能运行的 在网上查了一下应该是VSCODE的pylint代码规范的问题,不会影响结果的,不过确实是太丑了这个红色波浪线 于是找了一下方法,可以在setting.json文件中的 "python....
  • 【why】 在Executor 框架中标识一种异步任务, 此外也可以用来表示一些时间较长的计算,这些计算可以... 三种状态:等待运行运行中、执行完成,其中执行完成又分为正常结束、由于取消而结束、由于异常而结束。 ...
  • Callable与FutureTask

    2019-04-07 15:34:11
    提FutureTask之前,需要先提及Callable接口。 一般来讲,java中创建线程常用两种方式,一个是继承Thread类,一个是实现Runnable接口。第三种创建线程的方法就是实现Callable接口,实现接口中的call()方法。 通过...
  • Callable接口

    2021-07-19 11:25:02
    文章目录Callable概述Future 接口FutureTask使用 Callable 和 Future小结(重点) Callable概述 目前我们学习了有两种创建线程的方法-一种是通过创建 Thread 类,另一种是通过使用 Runnable 创建线程。但是,Runnable ...
  • Callable和Future接口Callable是类似于Runnable的接口,实现Callable接口的类和实现Runnable的类都是可被其它线程执行的任务。Callable和Runnable有几点不同:(1)Callable规定的方法是call(),而Runnable规定的方法...
  • 这两种方式的缺点是在任务完成后无法直接获取执行结果,必须通过共享变量或线程间通信,使用起来很不方便。 从Java 1.5开始提供了Callable和Future两个接口,通过使用它们可以在任务执行完毕后得到执行结果。 ...
  • callable和runable的比较

    2020-12-26 21:23:06
    废话不多说,直接看一下api里面对callable的解释:  Callable接口类似于Runnable ,因为它们都是为其实例可能由另一个线程执行的类设计的。 然而,A Runnable不返回结果,也不能抛出被检查的异常。  所以比起...
  • 摘要:本文从源码角度深入解析Callable接口。
  • Future和Callable的使用

    2021-12-19 10:02:55
    方法get()结合ExecutorService中的submit(Callable<T>)的使用 方法submit(Callable<T>)可以执行参数为Callable的任务。 方法get()用于获取返回值。 package cn.java.Concurrency; import java....
  • 深入理解Callable

    万次阅读 2017-08-22 18:34:42
    概述Callable和Runnbale一样代表着任务,区别在于Callable有返回值并且可以抛出异常。其使用如下: public class CallableDemo { static class SumTask implements Callable<Long> { @Override public Long ...
  • 使用Callable进行多线程处理数据 import java.util.ArrayList; import java.util.List; import java.util.Random; import java.util.concurrent.*; /** * created by jasonwag * on 2019/7/22 11:03 */ public ...
  • 这里写自定义目录标题python运行报错TypeError: 'int' object is not callable python运行报错TypeError: ‘int’ object is not callable 意思:int类型不可被调用 解决方法:看是不是函数名与变量名重复定义了 ...
  • 聊一聊自己对Runnable和Callable之间差别的看法
  • 本文纯干货,从源码角度深入解析Callable接口,希望大家踏下心来,打开你的IDE,跟着文章看源码,相信你一定收获不小。 1.Callable接口介绍 Callable接口是JDK1.5新增的泛型接口,在JDK1.8中,被声明为函数式接口...
  • Java并发编程源码分析系列:上一篇分析了线程池的执行原理,主要关于线程池的生命周期和任务如何在池里创建、运行和终止。不过上次研究的是execute方法,执行的是Runnable任务,它不返回任何值。如果希望任务完成后...
  • Callable不能直接创建线程 Callable运行过程中可以抛出异常 public interface Callable<V> { V call() throws Exception; } Runnable: Runnable不能返回任何结果 Runnable可以直接创建线程 Runnable运行过程中不能...
  • Callable异步原理简析

    2019-05-16 11:58:45
    Callable异步执行,应该不会陌生,那么在java中是怎么用的呢?又是如何实现的?下面我们循序渐进,慢慢分析。 先看一个例子,实现Callable接口,进行异步计算: package com.demo; import j...
  • Future和Callable Callable和Runnable主要区别为: Callable接口的call)方法可以有返回值,而Runnable接口的run()方法没有返回值。 Callable 接口的call0)方法可以声明抛出异常,而Runnable接口的run()方法不可以...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 53,586
精华内容 21,434
关键字:

callable怎么直接运行