2. 并发处理

2017-11-22  本文已影响0人  Wille_Li

1. Executors

1.1 Callable &  Future

Callable:可以理解为有返回值的Runnable,具体实现返回内容主要靠Future接口的实现处理。

Callable源码

Future:Callable返回值监控接口。

Furure源码

canncel:取消线程操作

IsCancelled:判断是否取消成功

IsDone:判断是否执行完毕

get:等待任务执行结束,获取返回结果

get(long, TimeUnit): 等待任务执行结束,如果超过指定时间,则中断等待。

1.2 线程中断

线程的interrupt() 和 如何处理InterruptedException进行处理。

不要使用stop() 处理中断,这样有可能存在数据不一致,因为stop会强制释放锁,杀死线程。

在线程内使用Thread.interrupted() 判断中断,并抛出InterruptedException错误。

在捕获错误catch内使用 Thread.currentThread().interrupt() 中断当前线程。

参考博文:https://www.ibm.com/developerworks/cn/java/j-jtp05236.html

1.3 ThreadFactory

线程工厂接口,不用使用new Thread 去新建线程。

Executors内部实现了默认的ThreadFactory 用于创建Thread的

1.4 ThreadPool

线程池的优点: 1. 降低资源浪费,通过重复利用线程减少创建和销毁的消耗;2. 提高响应速度,不用等待创建线程的时间;3. 提供线程的可管理性,防止线程数量不断增加,统一管理。

线程池组成结构:

一个线程池wokers是个Worker set,可用线程都在这个集合里面。

一个任务队列workQueue 是个BlockingQueue,当任务submit到线程池里,先会加入到这个队列里,缓冲队列。

当线程池启动时,会从workQueue内获取Runnable到Worker内执行。

当线程池没有闲置线程时,处理请求会存在队列workQueue中。

线程再次闲置就会去队列获取处理请求。

JDK创建默认线程池:

Executors内初始化线程池的方法

    1). newFixedThreadPool(吞吐相对于newCachedThreadPool会差一点,长请求、短请求都可以使用)

        固定大小的线程池,底层队列使用LinedBlockingQueue队列。

newFixedThreadPool

    2). newCachedThreadPool(大吞吐处理,短处理请求)

        这个线程池根据需要(新任务到来时)创建新的线程,如果有空闲线程则会重复使用,线程空闲了60秒后会被回收。阻塞线程池,没有限制大小,底层队列使用SynchronousQueue,所以这个线程池的吞吐量更大,但是没有闲置大小,有可能会出现线程过多导致内存溢出情况。所以使用这个线程池需要注意控制线程池大小。

newCachedThreadPool

    3). newScheduledThreadPool(定时处理,延迟处理)

        这个线程池方法返回ScheduledThreadPoolExecutor,底层使用队列DelayedQueue达到延迟执行的效果,可以用于定时任务。

newScheduledThreadPool ScheduledExecutorService

1.5 Fork, Join

    Fork/Join框架是Java7提供了的一个用于并行执行任务的框架, 是一个把大任务分割成若干个小任务,最终汇总每个小任务结果后得到大任务结果的框架。充分利用多核环境。

处理步骤:

    1). 拆分小任务,知道拆分到足够小为止;

    2). 执行任务,分割的子任务双端队列里,几个线程从队列两端获取任务执行;

    3). 合并任务, 执行完的任务结果统一存放在一个队列里,启动一个线程从队列里拿数据并合并这些数据。

主要实现:

    ForkJoinPool ----- ExecutorService 的实现

        由ForkJoinTask数组和ForkJoinWorkerThread数组组成,ForkJoinTask数组负责存放程序提交给ForkJoinPool的任务,而ForkJoinWorkerThread数组负责执行这些任务。

    ForkJoinTask ---- Future 的实现

        主要用于分割任务,合并任务,还有任务的处理过程。

        ForkJoinWorkerThread 在ForkJoinTask内会用当前线程添加任务,

        里面存在一个任务队列

        子类:

        RecursiveAction:用于没有返回结果的任务。

        RecursiveTask :用于有返回结果的任务。

        具体原理详情:Fork/Join 原理

1.6 守护线程 & 用户线程

守护线程: 服务于用户线程的线程,但是守护线程会因为没有用户线程而中断。优先级较低。

用户线程: 前台执行线程,主线程执行完用户线程还在。

上一篇下一篇

猜你喜欢

热点阅读