ImageVerifierCode 换一换
格式:DOCX , 页数:7 ,大小:17.45KB ,
资源ID:10536781      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/10536781.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(Java程序员必须掌握的线程知识.docx)为本站会员(b****7)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

Java程序员必须掌握的线程知识.docx

1、Java程序员必须掌握的线程知识Java程序员必须掌握的线程知识Callable和FutureCallable和Future出现的原因创建线程的2种方式,一种是直接继承Thread,另外一种就是实现Runnable接口。这2种方式都有一个缺陷就是:在执行完任务之后无法获取执行结果。如果需要获取执行结果,就必须通过共享变量或者使用线程通信的方式来达到效果,这样使用起来就比较麻烦。而自从Java 1.5开始,就提供了Callable和Future,通过它们可以在任务执行完毕之后得到任务执行结果。Callable和Future介绍Callable接口代表一段可以调用并返回结果的代码;Future接口

2、表示异步任务,是还没有完成的任务给出的未来结果。所以说Callable用于产生结果,Future用于获取结果。Callable接口使用泛型去定义它的返回类型。Executors类提供了一些有用的方法在线程池中执行Callable内的任务。由于Callable任务是并行的(并行就是整体看上去是并行的,其实在某个时间点只有一个线程在执行),我们必须等待它返回的结果。java.util.concurrent.Future对象为我们解决了这个问题。在线程池提交Callable任务后返回了一个Future对象,使用它可以知道Callable任务的状态和得到Callable返回的执行结果。Future提供

3、了get()方法让我们可以等待Callable结束并获取它的执行结果。Callable与Runnablejava.lang.Runnable吧,它是一个接口,在它里面只声明了一个run()方法:public interface Runnable public abstract void run();由于run()方法返回值为void类型,所以在执行完任务之后无法返回任何结果。Callable位于java.util.concurrent包下,它也是一个接口,在它里面也只声明了一个方法,只不过这个方法叫做call():public interface Callable /* * Computes

4、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()函数返回的类型就是传递进来的V类型。那么怎么使用Callable呢?一般情况下是配合ExecutorService来使用的,在ExecutorService接口中声明了若干个submit方法的重载版本: Future submit(Callab

5、le task); Future submit(Runnable task, T result);Future submit(Runnable task);第一个submit方法里面的参数类型就是Callable。暂时只需要知道Callable一般是和ExecutorService配合来使用的,具体的使用方法讲在后面讲述。一般情况下我们使用第一个submit方法和第三个submit方法,第二个submit方法很少使用。FutureFuture就是对于具体的Runnable或者Callable任务的执行结果进行取消、查询是否完成、获取结果。必要时可以通过get方法获取执行结果,该方法会阻塞直到任

6、务返回结果。Future类位于java.util.concurrent包下,它是一个接口:public interface Future boolean cancel(boolean mayInterruptIfRunning); boolean isCancelled(); boolean isDone(); V get() throws InterruptedException, ExecutionException; V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, Ti

7、meoutException;在Future接口中声明了5个方法,下面依次解释每个方法的作用:cancel方法用来取消任务,如果取消任务成功则返回true,如果取消任务失败则返回false。参数mayInterruptIfRunning表示是否允许取消正在执行却没有执行完毕的任务,如果设置true,则表示可以取消正在执行过程中的任务。如果任务已经完成,则无论mayInterruptIfRunning为true还是false,此方法肯定返回false,即如果取消已经完成的任务会返回false;如果任务正在执行,若mayInterruptIfRunning设置为true,则返回true,若mayI

8、nterruptIfRunning设置为false,则返回false;如果任务还没有执行,则无论mayInterruptIfRunning为true还是false,肯定返回true。isCancelled方法表示任务是否被取消成功,如果在任务正常完成前被取消成功,则返回 true。isDone方法表示任务是否已经完成,若任务完成,则返回true;get()方法用来获取执行结果,这个方法会产生阻塞,会一直等到任务执行完毕才返回;get(long timeout, TimeUnit unit)用来获取执行结果,如果在指定时间内,还没获取到结果,就直接返回null。也就是说Future提供了三种功能

9、:1)判断任务是否完成;2)能够中断任务;3)能够获取任务执行结果。因为Future只是一个接口,所以是无法直接用来创建对象使用的,因此就有了下面的FutureTask。FutureTaskFutureTask实现了RunnableFuture接口,这个接口的定义如下:public interface RunnableFuture extends Runnable, Future void run(); 可以看到这个接口实现了Runnable和Future接口,接口中的具体实现由FutureTask来实现。这个类的两个构造方法如下 :public FutureTask(Callable cal

10、lable) if (callable = null) throw new NullPointerException(); sync = new Sync(callable); public FutureTask(Runnable runnable, V result) sync = new Sync(Executors.callable(runnable, result); 如上提供了两个构造函数,一个以Callable为参数,另外一个以Runnable为参数。这些类之间的关联对于任务建模的办法非常灵活,允许你基于FutureTask的Runnable特性(因为它实现了Runnable接口)

11、,把任务写成Callable,然后封装进一个由执行者调度并在必要时可以取消的FutureTask。FutureTask可以由执行者调度,这一点很关键。它对外提供的方法基本上就是Future和Runnable接口的组合:get()、cancel、isDone()、isCancelled()和run(),而run()方法通常都是由执行者调用,我们基本上不需要直接调用它。一个FutureTask的例子public class MyCallable implements Callable private long waitTime; public MyCallable(int timeInMillis

12、) this.waitTime=timeInMillis; Override public String call() throws Exception Thread.sleep(waitTime); /return the thread name executing this callable task return Thread.currentThread().getName(); public class FutureTaskExample public static void main(String args) MyCallable callable1 = new MyCallable

13、(1000); / 要执行的任务 MyCallable callable2 = new MyCallable(2000); FutureTask futureTask1 = new FutureTask(callable1);/ 将Callable写的任务封装到一个由执行者调度的FutureTask对象 FutureTask futureTask2 = new FutureTask(callable2); ExecutorService executor = Executors.newFixedThreadPool(2); / 创建线程池并返回ExecutorService实例 executo

14、r.execute(futureTask1); / 执行任务 executor.execute(futureTask2); while (true) try if(futureTask1.isDone() & futureTask2.isDone()/ 两个任务都完成 System.out.println(Done); executor.shutdown(); / 关闭线程池和服务 return; if(!futureTask1.isDone() / 任务1没有完成,会等待,直到任务完成 System.out.println(FutureTask1 output=+futureTask1.ge

15、t(); System.out.println(Waiting for FutureTask2 to complete); String s = futureTask2.get(200L, TimeUnit.MILLISECONDS); if(s !=null) System.out.println(FutureTask2 output=+s); catch (InterruptedException | ExecutionException e) e.printStackTrace(); catch(TimeoutException e) /do nothing 运行如上程序后,可以看到一段时间内没有输出,因为get()方法等待任务执行完成然后才输出内容.输出结果如下:FutureTask1 output=pool-1-thread-1Waiting for FutureTask2 to completeWaiting for FutureTask2 to completeWaiting for FutureTask2 to completeWaiting for FutureTask2 to completeWaiting for FutureTask2 to completeFutureTask2 output=pool-1-thread-2Done

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1