Java多线程的开发技巧_第1页
Java多线程的开发技巧_第2页
Java多线程的开发技巧_第3页
Java多线程的开发技巧_第4页
Java多线程的开发技巧_第5页
已阅读5页,还剩3页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

本文格式为Word版,下载可任意编辑——Java多线程的开发技巧Java多线程的开发技巧

导语:好多开发者谈到Java多线程开发,仅仅停留在newThread….start或直接使用Executor框架这个层面,对于线程的管理和操纵却不够深入,下面是Java多线程的开发技巧,一起来学习下吧:

不使用线程池的缺点

有些开发者图省事,遇到需要多线程处理的地方,直接newThread….start,对于一般场景是没问题的,但假设是在并发苦求很高的处境下,就会有些隐患:

1.新建线程的开销。线程虽然比进程要轻量大量,但对于JVM来说,新建一个线程的代价还是挺大的,决不同于新建一个对象。

2.资源消耗量。没有一个池来限制线程的数量,会导致线程的数量直接取决于应用的并发量,这样有潜在的线程数据巨大的可能,那么资源消耗量将是巨大的。

3.稳定性。当线程数量超过系统资源所能承受的程度,稳定性就会成问题。

制定执行策略

在每个需要多线程处理的地方,不管并发量有多大,需要考虑线程的执行策略:

1.任务以什么依次执行

2.可以有多少个任务并发执行

3.可以有多少个任务进入等待执行队列

4.系统过载的时候,理应放弃哪些任务?如何通知到应用程序?

5.一个任务的执行前后理应做什么处理

线程池的类型

不管是通过Executors创造线程池,还是通过Spring来管理,都得领会知道有哪几种线程池:

FixedThreadPool:定长线程池,提交任务时创造线程,直到池的最大容量,假设有线程非预期终止,会补充新线程

CachedThreadPool:可变线程池,它犹如一个弹簧,假设没有任务需求时,它回收空闲线程,假设需求增加,那么按需增加线程,不对池的大小做限制

SingleThreadExecutor:单线程。处理不过来的任务会进入FIFO队列等待执行

SecheduledThreadPool:周期性线程池。支持执行周期性线程任务

其实,这些不同类型的线程池都是通过构建一个ThreadPoolExecutor来完成的,所不同的是corePoolSize,maximumPoolSize,keepAliveTime,unit,workQueue,threadFactory这么几个参数。概括可以参见JDKDOC。

线程池饱和策略

由以上线程池类型可知,除了CachedThreadPool其他线程池都有饱和的可能,当饱和以后就需要相应的策略处理苦求线程的任务,ThreadPoolExecutor采取的方式通过队列来存储这些任务,当然会根据池类型不同选择不同的队列,譬如FixedThreadPool和SingleThreadExecutor默认采用的是无限长度的LinkedBlockingQueue。但从系统可控性讲,最好的做法是使用定长的ArrayBlockingQueue或有限的LinkedBlockingQueue,并且当达成上限时通过ThreadPoolExecutor.setRejectedExecutionHandler方法设置一个拒绝任务的策略,JDK供给了AbortPolicy、CallerRunsPolicy、DiscardPolicy、DiscardOldestPolicy几种策略,概括差异可见JDKDOC

线程无凭借性

多线程任务设计上尽量使得各任务是独立无凭借的,所谓凭借性可两个方面:

线程之间的凭借性。假设线程有凭借可能会造成死锁或饥饿

调用者与线程的凭借性。调用者得监视线程的完成处境,影响可并发量

当然,在有些业务里切实需要确定的凭借性,譬如调用者需要得到线程完成后结果,传统的'Thread是不便完成的,由于run方法无返回值,只能通过一些共享的变量来传递结果,但在Executor框架里可以通过Future和Callable实现需要有返回值的任务,当然线程的异步性导致需要有相应机制来保证调用者能等待任务完成,关于Future和Callable的用法见下面的实例就一目了然了:

01publicclassFutureRenderer

02privatefinalExecutorServiceexecutor=...;

03voidrenderPageCharSequencesource

04finalListimageInfos=scanForImageInfosource;

05Callablelisttask=

06newCallablelist

07publicListcall

08Listresult

09=newArrayList;

10forImageInfoimageInfo:imageInfos

11result.addimageInfo.downloadImage;

12returnresult;

13

14;

15Futurelistfuture=executor.submittask;

16renderTextsource;

17try

18ListimageData=future.get;

19forImageDatadata:imageData

20renderImagedata;

21catchInterruptedExceptione

22//Re-assertthethreadsinterruptedstatus

23Thread.currentTerrupt;

24//Wedontneedtheresult,socancelthetasktoo

25future.canceltrue;

26catchExecutionExceptione

27throwlaunderThrowablee.getCause;

28

29

30

以上代码关键在于ListimageData=future.get;假设Callable类型的任务没有执行完时,调用者会阻塞等待。不过这样的方式还是得精心使用,很轻易造成不良设计。另外对于这种需要等待的场景,就需要设置一个最大容忍时间timeout,设置方法可以在future.get加上timeout参数,或是再调用ExecutorService.invokeAll加上timeout参数

线程的取消与关闭

一般的处境下是让线程运行完成后自行关闭,但有些时候也会中途取消或关闭线程,譬如以下处境:

调用者强制取消。譬如一个长时间运行的任务,用户点击”cancel”按钮强行取消

限时任务

发生不成处理的任务

整个应用程序或服务的关闭

因此需要有相应的取消或关闭的方法和策略来操纵线程,一般有以下方法:

1通过变量标识来操纵

这种方式对比老土,但使用得分外广泛,主要缺点是对有阻塞的操作操纵不好,代码例如如下所示:

01publicclassPrimeGeneratorimplementsRunnable

02@GuardedBythis

03privatefinalListprimes

04=newArrayList;

05privatevolatilebooleancancelled;

06publicvoidrun

07BigIntegerp=BigInteger.ONE;

08while!cancelled

09p=p.nextProbablePrime;

10synchronizedthis

11primes.addp;

12

13

14

15publicvoidcancelcancelled=true;

16publicsynchronizedListget

17returnnewArrayListprimes;

18

19

2中断

中断通常是实现取消最明智的选择,但线程自身需要支持中断处理,并且要处理好中断策略,一般响应中断的方式有两种:

处理完中断清理后持续传递中断奇怪InterruptedException

调用interrupt方法,使得上层能感知到中断奇怪

3取消不成中断阻塞

存在一些不成中断的阻塞,譬如:

java.io和java.nio中同步读写IO

Selector的异步IO

获取锁

对于这些线程的取消,那么需要特定处境特定对待,譬如对于socket阻塞,假设要安好取消,那么需要调用socket.close

4JVM的关闭

假设有任务需要在JVM关闭之前做一些清理工作,而不是被JVM强硬关闭掉,可以使用JVM的钩子技术,其实JVM钩子也只是个很普遍的技术,也就是用个map把一些需要JVM关闭前启动的任务保存下来,在JVM关闭过程中的某个环节来并发

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论