如果有人问题你,多线程可以有返回值吗?你怎么回答?
看下面例子,我定义了一个类实现了Callable 接口
public class MyCallable implements Callable<Object> { @Override public Object call() throws Exception { int i=10; Thread.sleep(10000); return i; } }
Callable如果要想得到返回值需要通过一个叫FutureTask的类帮助。简单的做法是这样的
public void test1() { try { FutureTask<Object> task = new FutureTask<Object>(new MyCallable()); new Thread(task).start(); System.out.println("task return : " + task.get().toString()); //get方法会一直阻塞,直到这个线程也就是call方法执行完毕 //可以通过调用isDone()来异步的询问是否已经完成。 } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } }
还有另外一种方式可以使用
public void test2(){ ExecutorService newCachedThreadPool = Executors.newCachedThreadPool(); Future<Object> future = newCachedThreadPool.submit(new MyCallable()); try { //同样可以通过future.isDone()来异步的知道线程是否已经处理完毕 System.out.println(future.get().toString()); }catch (Exception e) { e.printStackTrace(); } finally { newCachedThreadPool.shutdown(); } }
通过上面的例子,我们知道了可以通过callable得到一个线程的返回值了,那么使用callable算多线程吗?
其实第一个例子的一行代码已经暴露出他有多线程的特性了
new Thread(task).start();
看看这个task是什么的东西
public class FutureTask implements RunnableFuture //是RunnableFuture的一个实现 public interface RunnableFuture extends Runnable, Future //是Runnable 的子接口,这就是为什么可以放入Thread类中 // 同时他又有future的特性,得到返回值
为了彻底看清Future到底有什么,下面接口就是Future的完整定义了
public interface Future { public abstract boolean cancel(boolean flag); public abstract boolean isCancelled(); public abstract boolean isDone(); public abstract Object get() throws InterruptedException, ExecutionException; public abstract Object get(long l, TimeUnit timeunit) throws InterruptedException, ExecutionException, TimeoutException; }
现在知道了Callable是借助Runnable来实现多线程的功能,所以说它是多线程也说的过去。那么它是如何获得返回值的呢?
我们都知道线程的启动方法是start方法,然后线程内部调用了run()方法
public void run() { sync.innerRun(); } protected void set(Object obj) { sync.innerSet(obj); } public Object get() throws InterruptedException, ExecutionException { return sync.innerGet(); }
我们的调用都深入到了sync的方面里面去了。接下来
void innerRun() { if(!compareAndSetState(0, 1)) return; runner = Thread.currentThread(); if(getState() == 1) { Object obj; try { obj = callable.call(); //这时候调用我们覆写的call方法了 } catch(Throwable throwable) { setException(throwable); return; } set(obj);//执行完之后将结果放入存起来 } else { releaseShared(0); } }
如何存,很简单,存入事先准备好的属性中
void innerSet(Object obj) { int i; do { i = getState(); if(i == 2) return; if(i == 4) { releaseShared(0); return; } } while(!compareAndSetState(i, 2)); result = obj;//这么存的 releaseShared(0); done(); }
如何取
Object innerGet() throws InterruptedException, ExecutionException { acquireSharedInterruptibly(0); if(getState() == 4) throw new CancellationException(); if(exception != null) throw new ExecutionException(exception); else return result;
相关推荐
Java多线程设计模式上传文件Java多线程设计模式上传文件Java多线程设计模式上传文件Java多线程设计模式上传文件Java多线程设计模式上传文件Java多线程设计模式上传文件Java多线程设计模式上传文件Java多线程设计模式...
Java多线程读大文件 java多线程写文件:多线程往队列中写入数据
java多线程PPT 多线程基本概念 创建线程的方式 线程的挂起与唤醒 多线程问题
详细的讲解了java多线程的原理,并配有代码进行实战,适合java初学者和想对多线程有进一步了解的人。
一个java 多线程操作数据库应用程序!!!
java多线程并发查询数据库,使用线程池控制分页,并发查询。
java多线程处理数据库数据,使用并发包,无框架,可批量处数据库数据,进行增删改。。等等操作。
该文档总结了Java多线程相关的知识点,分享给大家,简单易懂!
Java线程:新特征-有返回值的线程 Java线程:新特征-锁(上) Java线程:新特征-锁(下) Java线程:新特征-信号量 Java线程:新特征-阻塞队列 Java线程:新特征-阻塞栈 Java线程:新特征-条件变量 Java线程...
多线程启动.java多线程启动.java多线程启动.java多线程启动.java
java多线程经典案例,线程同步、线程通信、线程阻塞等经典案例
Java多线程编程实战指南(核心篇) 高清pdf带目录 随着现代处理器的生产工艺从提升处理器主频频率转向多核化,即在一块芯片上集成多个处理器内核(Core),多核处理器(Multicore Processor)离我们越来越近了――如今...
java多线程,对多线程,线程池进行封装,方便使用
java多线程模拟队列实现排队叫号,多线程模拟排队叫号取号 java多线程模拟队列实现排队叫号,多线程模拟排队叫号取号
JAVA多线程端点续传下载JAVA多线程端点续传下载JAVA多线程端点续传下载JAVA多线程端点续传下载JAVA多线程端点续传下载JAVA多线程端点续传下载JAVA多线程端点续传下载JAVA多线程端点续传下载JAVA多线程端点续传下载...
详细的讲述了多线程的各种用法 Java线程:概念与原理 Java线程:创建与启动 Java线程:线程栈模型与线程的变量 Java线程:线程状态的转换 Java线程:线程的同步与锁 Java线程:线程的交互 Java线程:线程的调度-休眠...
Java多线程机制 9.1 Java中的线程 9.2 Thread的子类创建线程 9.3 使用Runable接口 9.4 线程的常用方法 9.5 GUI线程 9.6 线程同步 9.7 在同步方法中使用wait()、notify 和notifyAll()方法 9.8 挂起、恢复和终止线程 ...
java多线程处理大数据,可根据配置的线程数,任务去调度处理
资深Java专家10年经验总结,全程案例式讲解,首本全面介绍Java多线程编程技术的专著 结合大量实例,全面讲解Java多线程编程中的并发访问、线程间通信、锁等最难突破的核心技术与应用实践 Java多线程无处不在,如...