zoukankan      html  css  js  c++  java
  • java并发Executors学习笔记

    java并发(1)-Executors
    关于java创建多线程常用的两种方式,我就不多说了,无非就是实现Runnable和继承Thread。那么我们现在来说说其他的方法。

    Executors是什么
    Executors,我们称之为执行器,用于管理Thread对象,简化并发过程,其在客户端和任务执行之间提供了一个间接层。由中介执行任务。无需管理线程的生命周期。
    我们先是实现一个Runnable的类,其功能非常简单,就是在一个计数器,而且对于每一个创建的对象来说,其id都不一样,方便我们识别。

    class MyCountDownRunnale implements Runnable {
    private int countDown = 10;
    private static int taskCount = 0;
    private final int id = taskCount ++;
    public MyCountDownRunnale(){}
    public MyCountDownRunnale(int countDown) {
    this.countDown = countDown;
    }
    @Override
    public void run() {
    while (countDown -- > 0) {
    System.out.print(toString());
    Thread.yield();//线程都让出使用权,加入竞争。
    }
    }
    @Override
    public String toString() {
    return "$" + id + "<" + Thread.currentThread().getId() + ">(" + (countDown > 0 ? countDown : "Zero") + "), ";
    }
    }
    CachedThreadPool方式
    如下代码:

    ExecutorService exec = Executors.newCachedThreadPool();
    for (int i = 0; i < 5; i ++) {
    exec.execute(new MyCountDownRunnale());
    }
    exec.shutdown();//防止新线程提交
    执行结果:

    $1<12>(9), $3<14>(9), $1<12>(8), $2<13>(9), $0<11>(9),
    $2<13>(8), $1<12>(7), $3<14>(8), $4<15>(9), $3<14>(7),
    $1<12>(6), $2<13>(7), $0<11>(8), $2<13>(6), $1<12>(5),
    $3<14>(6), $4<15>(8), $3<14>(5), $1<12>(4), $2<13>(5),
    $3<14>(4), $2<13>(4), $0<11>(7), $2<13>(3), $3<14>(3),
    $1<12>(3), $4<15>(7), $1<12>(2), $3<14>(2), $2<13>(2),
    $0<11>(6), $2<13>(1), $3<14>(1), $2<13>(Zero), $1<12>(1),
    $4<15>(6), $1<12>(Zero), $3<14>(Zero), $0<11>(5), $4<15>(5),
    $0<11>(4), $4<15>(4), $0<11>(3), $4<15>(3), $0<11>(2),
    $4<15>(2), $0<11>(1), $4<15>(1), $0<11>(Zero), $4<15>(Zero),
    FixedThreadPool方式
    如下代码:

    ExecutorService exec =Executors.newFixedThreadPool(4);
    for (int i = 0; i < 5; i ++) {
    exec.execute(new MyCountDownRunnale());
    }
    exec.shutdown();//防止新线程提交
    执行结果:

    $0<11>(9), $3<14>(9), $2<13>(9), $1<12>(9), $2<13>(8),
    $3<14>(8), $0<11>(8), $3<14>(7), $0<11>(7), $2<13>(7),
    $1<12>(8), $2<13>(6), $0<11>(6), $3<14>(6), $0<11>(5),
    $2<13>(5), $1<12>(7), $2<13>(4), $0<11>(4), $3<14>(5),
    $0<11>(3), $2<13>(3), $1<12>(6), $2<13>(2), $3<14>(4),
    $2<13>(1), $0<11>(2), $1<12>(5), $0<11>(1), $2<13>(Zero),
    $3<14>(3), $0<11>(Zero), $1<12>(4), $1<12>(3), $3<14>(2),
    $1<12>(2), $4<13>(9), $1<12>(1), $1<12>(Zero), $3<14>(1),
    $4<13>(8), $3<14>(Zero), $4<13>(7), $4<13>(6), $4<13>(5),
    $4<13>(4), $4<13>(3), $4<13>(2), $4<13>(1), $4<13>(Zero),
    SingleThreadExecutor方式
    如下代码:

    ExecutorService exec = Executors.newSingleThreadExecutor();
    for (int i = 0; i < 5; i ++) {
    exec.execute(new MyCountDownRunnale());
    }
    exec.shutdown();//防止新线程提交
    执行结果:

    $0<11>(9), $0<11>(8), $0<11>(7), $0<11>(6), $0<11>(5),
    $0<11>(4), $0<11>(3), $0<11>(2), $0<11>(1), $0<11>(Zero),
    $1<11>(9), $1<11>(8), $1<11>(7), $1<11>(6), $1<11>(5),
    $1<11>(4), $1<11>(3), $1<11>(2), $1<11>(1), $1<11>(Zero),
    $2<11>(9), $2<11>(8), $2<11>(7), $2<11>(6), $2<11>(5),
    $2<11>(4), $2<11>(3), $2<11>(2), $2<11>(1), $2<11>(Zero),
    $3<11>(9), $3<11>(8), $3<11>(7), $3<11>(6), $3<11>(5),
    $3<11>(4), $3<11>(3), $3<11>(2), $3<11>(1), $3<11>(Zero),
    $4<11>(9), $4<11>(8), $4<11>(7), $4<11>(6), $4<11>(5),
    $4<11>(4), $4<11>(3), $4<11>(2), $4<11>(1), $4<11>(Zero),
    三者的区别
    看了三个不同的执行结果,我想大家都能知道1和2更3的区别了吧,
    1、第三种方式如其名,单线程跑的,他会把提交的任务,按照顺序执行,而且还是在同一个线程里执行的。
    2、那第一种和第二种的区别是什么呢?java培训技术构造方法的参数不一样,第二种方式中的参数代表的意思是,一次性预先执行代价昂贵的线程分配,之后就可直接使用了,不过不能滥用,因为数量有限。而第一种就是,执行过程中通常创建所需的数量的线程,然后回收旧线程的时候,停止创建线程。
    3、他们两个除了这个区别之外,还有一个重要的特性,就是FixedThreadPool保证了“没有两个线程”会被并发调用。
    4、如果一个线程实例请求加入FixedThreadPool时,如果该实例不存在,且没有达到线程池数目上线,则会创建一个实例,否则,会先加入等待序列,当FixedThreadPool中有一个线程停止并移出线程池后,线程实例才能加入线程池。
    5、CachedThreadPool中线程实例默认超时时间为60s,超过这个时间,线程实例停止并被移出CachedThreadPool,适用于生存期短、异步的线程任务。FixedThreadPool没有超时机制,适用于稳定且并发线程任务。关于这点,可以看源码中的代码Executors.java:
    如下,第三个参数就是超时的时间设置。0就是不超时。

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

  • 相关阅读:
    hdu 5387 Clock (模拟)
    CodeForces 300B Coach (并查集)
    hdu 3342 Legal or Not(拓扑排序)
    hdu 3853 LOOPS(概率DP)
    hdu 3076 ssworld VS DDD(概率dp)
    csu 1120 病毒(LICS 最长公共上升子序列)
    csu 1110 RMQ with Shifts (线段树单点更新)
    poj 1458 Common Subsequence(最大公共子序列)
    poj 2456 Aggressive cows (二分)
    HDU 1869 六度分离(floyd)
  • 原文地址:https://www.cnblogs.com/gojava/p/4469411.html
Copyright © 2011-2022 走看看