美文网首页
2. 并发处理

2. 并发处理

作者: Wille_Li | 来源:发表于2017-11-22 19:31 被阅读0次

    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 守护线程 & 用户线程

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

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

    相关文章

      网友评论

          本文标题:2. 并发处理

          本文链接:https://www.haomeiwen.com/subject/kxmzmxtx.html