-
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,所以线程未执行完就会等待,造成主线程的阻塞。这里可以用异步通信解决。更多相关内容 -
解决’tuple’ object is not callable的报错-python变量命名错误
2020-12-22 02:48:09初学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:132.1 使用Callable线程步骤: 3. 代码设计分析 4. 深入Callable具体源码,一步步查看如何执行: 4.1 Callbale接口---FutureTask构造方法的接口 4.2 FutureTask类和内部重要方法 4.3 RunnableFuture接口---继承了...目录
4.1 Callbale接口---FutureTask构造方法的接口
4.3 RunnableFuture接口 ---继承了Runnable,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()方法。注:一般推荐采用
实现接口的方式
来创建多线程 -
Java 通过线程池运行Runnable Callable FutureTask,通过Future获取返回值
2022-02-13 13:40:25Callable是可以获取返回值的Runnable,不过Callable只能通过线程池,来直接的提交任务。 如果通过Runnable来执行任务,则只能通过FutureTask来获取返回值。 线程池ExecutoerService的execute()方法,只接收... -
Callable实现多线程及线程运行状状态
2019-08-02 14:39:07Callable实现多线程 从最传统来讲如果要进行多线程的实现肯定要依靠的就是Runnable,但是Runnable接口有一个缺点:当线程执行完毕之后无法获取一个返回值,所以从JDK1.5之后就提出了一个新的线程实现接口:java.util... -
详解Java Callable接口实现多线程的方式
2021-03-19 10:09:11在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中,被声明为函数式接口... -
Callable和FutureTask的使用
2021-11-16 00:55:191 Callable 接口 接口内部仅有一个call()方法,方法返回类型为接口泛型定义的类型。实现类重写内部方法后,通过Future接口的包装类进行包装,来实现Runable接口,从而能够开启新的线程。与Runable不同的是:... -
使用Callable接口创建线程
2021-09-18 17:17:06为了支持此功能,Java中提供了Callable接口。 当然了还可以使用线程池创建线程。 Callable接口和Runnable接口的区别 Callable接口中定义了需要有返回的任务需要实现的call方法。 比如主线程让一个子线程去执行任务,... -
VSCODE的pylint忽略其规范错误,但运行没错;torch.tensor is not callable
2020-11-01 14:30:16后面测试了一下最简单的程序,发现是能运行的 在网上查了一下应该是VSCODE的pylint代码规范的问题,不会影响结果的,不过确实是太丑了这个红色波浪线 于是找了一下方法,可以在setting.json文件中的 "python.... -
Callable、Future、FutureTask 运行流程
2019-08-26 07:36:11【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 ... -
Java多线程之Callable接口的实现
2021-03-08 05:06:56Callable和Future接口Callable是类似于Runnable的接口,实现Callable接口的类和实现Runnable的类都是可被其它线程执行的任务。Callable和Runnable有几点不同:(1)Callable规定的方法是call(),而Runnable规定的方法... -
使用Callable、Future进行并行编程
2021-04-08 21:03:37这两种方式的缺点是在任务完成后无法直接获取执行结果,必须通过共享变量或线程间通信,使用起来很不方便。 从Java 1.5开始提供了Callable和Future两个接口,通过使用它们可以在任务执行完毕后得到执行结果。 ... -
callable和runable的比较
2020-12-26 21:23:06废话不多说,直接看一下api里面对callable的解释: Callable接口类似于Runnable ,因为它们都是为其实例可能由另一个线程执行的类设计的。 然而,A Runnable不返回结果,也不能抛出被检查的异常。 所以比起... -
从源码角度详解Java的Callable接口
2021-07-28 14:42:04摘要:本文从源码角度深入解析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 ... -
java 多线程Callable,有返回值多线程,当线程获取到需要的值,则停止其他线程,直接输出结果,继续运行下面...
2019-07-22 15:31:45使用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
2021-07-02 09:32:21这里写自定义目录标题python运行报错TypeError: 'int' object is not callable python运行报错TypeError: ‘int’ object is not callable 意思:int类型不可被调用 解决方法:看是不是函数名与变量名重复定义了 ... -
简单说说Runnable和Callable
2022-03-21 23:42:07聊一聊自己对Runnable和Callable之间差别的看法 -
【高并发】深入解析Callable接口
2022-03-18 20:23:56本文纯干货,从源码角度深入解析Callable接口,希望大家踏下心来,打开你的IDE,跟着文章看源码,相信你一定收获不小。 1.Callable接口介绍 Callable接口是JDK1.5新增的泛型接口,在JDK1.8中,被声明为函数式接口... -
[怀旧并发05]分析Java线程池Callable任务执行原理
2021-03-22 10:48:44Java并发编程源码分析系列:上一篇分析了线程池的执行原理,主要关于线程池的生命周期和任务如何在池里创建、运行和终止。不过上次研究的是execute方法,执行的是Runnable任务,它不返回任何值。如果希望任务完成后... -
Java线程池之Callable接口
2020-12-15 10:36:12Callable不能直接创建线程 Callable运行过程中可以抛出异常 public interface Callable<V> { V call() throws Exception; } Runnable: Runnable不能返回任何结果 Runnable可以直接创建线程 Runnable运行过程中不能... -
Callable异步原理简析
2019-05-16 11:58:45Callable异步执行,应该不会陌生,那么在java中是怎么用的呢?又是如何实现的?下面我们循序渐进,慢慢分析。 先看一个例子,实现Callable接口,进行异步计算: package com.demo; import j... -
Java并发——Future和Callable
2020-06-24 11:36:23Future和Callable Callable和Runnable主要区别为: Callable接口的call)方法可以有返回值,而Runnable接口的run()方法没有返回值。 Callable 接口的call0)方法可以声明抛出异常,而Runnable接口的run()方法不可以...