美文网首页
BiBi - 并发编程 -15- Executor框架

BiBi - 并发编程 -15- Executor框架

作者: 奋飞的蜗牛ing | 来源:发表于2019-12-10 00:47 被阅读0次

    From:Java并发编程的艺术

    Java1.5之后把线程的工作单元和执行机制进行了分离。工作单元包括Runnable【无结果返回】和Callable【有结果返回】,执行机制由Executor框架提供。
    Executor可以把一个Runnable对象封装为一个Callable对象。

    ThreadPoolExecutor
        public ThreadPoolExecutor(int corePoolSize,
                                  int maximumPoolSize,
                                  long keepAliveTime,
                                  TimeUnit unit,
                                  BlockingQueue<Runnable> workQueue) { }
    
    FixedThreadPool
    public static ExecutorService newFixedThreadPool(int nThreads) {
            return new ThreadPoolExecutor(nThreads, nThreads,
                                          0L, TimeUnit.MILLISECONDS,
                                          new LinkedBlockingQueue<Runnable>());
        }
    
    SingleThreadExecutor
        public static ExecutorService newSingleThreadExecutor() {
            return new FinalizableDelegatedExecutorService
                (new ThreadPoolExecutor(1, 1,
                                        0L, TimeUnit.MILLISECONDS,
                                        new LinkedBlockingQueue<Runnable>()));
        }
    

    SingleThreadExecutor和FixedThreadPool就前两个参数不一样。

    CachedThreadPool
        public static ExecutorService newCachedThreadPool() {
            return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                          60L, TimeUnit.SECONDS,
                                          new SynchronousQueue<Runnable>());
        }
    

    使用SynchronousQueue没有容量的队列,每个插入操作必须等待另一个线程的对应移除操作。CachedThreadPool使用SynchronousQueue,把主线程提交的任务传递给空闲线程来执行【在60秒内】。

    ScheduledThreadPoolExecutor
        public ScheduledThreadPoolExecutor(int corePoolSize) {
            super(corePoolSize, Integer.MAX_VALUE,
                  DEFAULT_KEEPALIVE_MILLIS, MILLISECONDS,
                  new DelayedWorkQueue());
        }
    

    ScheduledThreadPoolExecutor继承ThreadPoolExecutor。DelayQueue是一个无界队列,它里面封装了一个PriorityQueue,会按照时间先后顺序进行排序,如果时间相同,则再按照任务添加的先后顺序。
    执行过程:先从DelayQueue中获取已到期的ScheduleFutureTask进行执行,然后修改这个任务的time变量为下次执行的时间,最后将修改time后的ScheduleFutureTask放回到DelayQueue中。

    FutureTask 异步计算结果

    FutureTask继承了Future接口和Runnable接口。
    构造函数:

    FutureTask(Callable<V> callable) { }
    FutureTask(Runnable runnable, V result) { }
    

    开启线程的方法:

    //方法一:继承于Thread
    new Thread() {
      @Override
      public void run() {
      }
    }.start();
    
    //方法二:实现Runnable接口
    new Thread(new Runnable() {
      @Override
      public void run() {
    
      }
    }).start();
    
    //方法三:FutureTask + Callable, 有结果返回
    FutureTask<String> res = new FutureTask<String>(new Callable<String>() {
      @Override
      public String call() throws Exception {
        return null;
      }
    }).run();
    
    //方法四:FutureTask + Runnable, 有结果返回
    String result = null;
    new FutureTask<String>(new Runnable() {
      @Override
      public void run() {
    
      }
    }, result).run();
    

    注意:FutureTask调用run方法启动线程而不是start方法。

    FutureTask使用场景:当一个线程需要等待另一线程把某个任务执行完后才能继续执行。
    FutureTask的实现基于AQS同步器。FutureTask的acquire操作对应为get()/get(long timeout);release操作对应为run方法或cancel方法。

    相关文章

      网友评论

          本文标题:BiBi - 并发编程 -15- Executor框架

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