多线程

Welcome use !

多线程

Jdk1.5之后加入了java.util.concurrent包。

线程池作用:就是限制系统中执行线程的数量

1.减少了创建和销毁线程的次数,每个工作线程都可以被重复利用,可执行多个任务。

2.可以根据系统的承受能力,调整线程池中工作线线程的数目,防止因为消耗过多的内存,而把服务器累趴下(每个线程需要大约1MB内存,线程开的越多,消耗的内存也就越大,最后死机)。

核心类:
ExecutorService 真正的线程池接口
ScheduledExecutorService 能和Timer/TimerTask类似,解决那些需要任务重复执行的问题。
ThreadPoolExecutor ExecutorService的默认实现
ScheduledThreadPoolExecutor 继承ThreadPoolExecutor的ScheduledExecutorService接口实现,周期性任务调度的类实现。
ThreadPoolExecutor详解
1
2
3
4
5
6
7
8
9
10
11
12
//完整的构造方法
/**
corePoolSize - 池中所保存的线程数,包括空闲线程。
maximumPoolSize-池中允许的最大线程数。
keepAliveTime - 当线程数大于核心时,此为 终止前 多余的空闲线程 等待新任务 的 最长时间。
unit - keepAliveTime 参数的时间单位。
workQueue - 执行前用于保持任务的队列。此队列仅保持由 execute方法提交的 Runnable任务。
threadFactory - 执行程序创建新线程时使用的工厂。
handler - 由于超出线程范围和队列容量而使执行被阻塞时所使用的处理程序。
ThreadPoolExecutor是Executors类的底层实现
*/
ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler)
四种线程池,Java通过Executors提供四种线程池
线程池 特点 注意
newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待 但在线程池空闲时,即线程池中没有可运行任务时,它不会释放工作线程,还会占用一定的系统资源
newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行
newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行
newCachedThreadPool 创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程 一定要注意控制任务的数量,否则,由于大量线程同时运行,很有会造成系统瘫痪
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
多线程案例

1.多线程异步下载

​ 在做报表系统的时候,各个部门的报表数据,有提供 下载 报表数据的功能,由于部门很多,或者报表数据很大,为了不耽误工作人员等待下载的时间,实现多线程异步下载,把下载任务添加到线程池中,当任务完成,下载完毕。工作人员去自己的任务中心或者通知中心查看下载状态,如果完成,去相应的地方找到自己的报表即可。

2.多线程爬虫

​ 在做爬虫系统的时候,一个定时任务启动时候,可能会有很多爬虫进行并发爬取,我们采用线程池+队列的方法控制这个时间段的爬虫数据,保证系统不出现内存溢出或者服务器宕机的状况。

线程监控

Jdk自带 bin\jconsole.exe

http://dl.iteye.com/upload/picture/pic/129496/a37b1415-36ac-30b8-baf6-10897bbf443a.jpg

http://dl.iteye.com/upload/picture/pic/129498/c518b086-b144-366c-884c-58a4bf985b05.jpg

参考链接