多线程之路---ExecutorService线程池(一)

  几种不同的ExecutorService线程池对象






newCachedThreadPool() 
--缓存型池子,先看池中有没有以前建立的线程,如果有就复用,如果没有就建一个新的线程加入池中
--缓存型池子通常用于执行一些生存期很短的异步型任务因此在一些面向连接的daemon型SERVER中用的不多
--能复用的线程,必须是timeout IDLE内的池中线程,缺省timeout是60s,超过这个IDLE时长,线程实例将被终止及移除池
注:放入CachedThreadPool的线程不必担心其结束,超过timeout不活动,会自动被终止。









newFixedThreadPool()
--newFixedThreadPool与cachedThreadPool差不多,也是能复用就用,但不能随时建新的线程
--其独特之处:任意时间点,最多只能存在固定数目的活动线程,此时如果有新的线程要建立,只能放在另外的队列中等待,直到当前的线程池中的某个线程被终止或直接被移除池
--和newCacheThreadPool不同,newFixedThreadPool没有IDLE机制,所以 newFixedThreadPool多数针对一些很稳定很固定的正规并发线程,多用于服务器
--从方法层的源码看,cache和fixed池调用的是同一个底层池,只不过参数不同:
    fixed池线程数固定,并且是0秒IDLE(无IDLE)
     cache池线程数支持0-IntegerMAX_VALUE,60秒IDLE。
--需调用shutdown()关闭
ScheduledThreadPool()
--调度线程池。这个池中的线程可以按schedule依次delay执行,或周期执行

SingleThreadExecutor
--单列线程,任意时间池中只能有一个线程
--用的是和cache池和fixed池相同的底层池,但线程数目是1-1,0秒IDLE(无IDLE)
Executor缺省线程工厂DefaultThreadFactory代码:
static class DefaultThreadFactory implements ThreadFactory {
       static final AtomicInteger poolNumber = new AtomicInteger(1);
       final ThreadGroup group;
       final AtomicInteger threadNumber = new AtomicInteger(1);
       final String namePrefix;

       DefaultThreadFactory() {
           SecurityManager s = System.getSecurityManager();
           group = (s != null)? s.getThreadGroup() :Thread.currentThread().getThreadGroup();
          
           namePrefix = “pool-” + poolNumber.getAndIncrement() + “-thread-“;
       }

       public Thread newThread(Runnable r) {
           Thread t = new Thread(group, r,namePrefix + threadNumber.getAndIncrement(),0);
           if (t.isDaemon())
               t.setDaemon(false);
           if (t.getPriority() != Thread.NORM_PRIORITY)
               t.setPriority(Thread.NORM_PRIORITY);
           return t;
       }
   }


自定义线程工厂ThreadFactory及使用示例:
public class TestExecutorService {

    public static void run(ExecutorService service){
        for(int i = 1;i<5;i++){
            final int taskId = i;
            service.execute(new Runnable() {

                @Override
                public void run() {
                    for(int j = 1;j<5;j++){
                        try {
                            Thread.sleep(1000);
                            System.out.println("当前线程"+Thread.currentThread().getName()+"第"+taskId+"次任务的第"+j+"次执行");
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }

                }
            });
        }
        service.shutdown();
    }
    public static void main(String[] args) {
        ExecutorService service1 = Executors.newCachedThreadPool(new ThreadFactory() {
            private AtomicInteger count = new AtomicInteger(); 
            @Override
            public Thread newThread(Runnable r) {
                 int c = count.incrementAndGet();  
                System.out.println("create num " + c + " Threads"); 
                return new Thread(r,"线程"+c);
            }
        });
        ExecutorService service2 = Executors.newFixedThreadPool(3,new ThreadFactory() {
            private AtomicInteger count = new AtomicInteger(); 
            @Override
            public Thread newThread(Runnable r) {
                 int c = count.incrementAndGet();  
                System.out.println("create num " + c + " Threads"); 
                return new Thread(r,"线程"+c);
            }
        });
        ExecutorService service3 = Executors.newSingleThreadExecutor();
        ExecutorService service4 = Executors.newScheduledThreadPool(3);
        run(service2);
    }
}
  几种不同的ExecutorService线程池对象






newCachedThreadPool() 
--缓存型池子,先看池中有没有以前建立的线程,如果有就复用,如果没有就建一个新的线程加入池中
--缓存型池子通常用于执行一些生存期很短的异步型任务因此在一些面向连接的daemon型SERVER中用的不多
--能复用的线程,必须是timeout IDLE内的池中线程,缺省timeout是60s,超过这个IDLE时长,线程实例将被终止及移除池
注:放入CachedThreadPool的线程不必担心其结束,超过timeout不活动,会自动被终止。









newFixedThreadPool()
--newFixedThreadPool与cachedThreadPool差不多,也是能复用就用,但不能随时建新的线程
--其独特之处:任意时间点,最多只能存在固定数目的活动线程,此时如果有新的线程要建立,只能放在另外的队列中等待,直到当前的线程池中的某个线程被终止或直接被移除池
--和newCacheThreadPool不同,newFixedThreadPool没有IDLE机制,所以 newFixedThreadPool多数针对一些很稳定很固定的正规并发线程,多用于服务器
--从方法层的源码看,cache和fixed池调用的是同一个底层池,只不过参数不同:
    fixed池线程数固定,并且是0秒IDLE(无IDLE)
     cache池线程数支持0-IntegerMAX_VALUE,60秒IDLE。
--需调用shutdown()关闭
ScheduledThreadPool()
--调度线程池。这个池中的线程可以按schedule依次delay执行,或周期执行

SingleThreadExecutor
--单列线程,任意时间池中只能有一个线程
--用的是和cache池和fixed池相同的底层池,但线程数目是1-1,0秒IDLE(无IDLE)
Executor缺省线程工厂DefaultThreadFactory代码:
static class DefaultThreadFactory implements ThreadFactory {
       static final AtomicInteger poolNumber = new AtomicInteger(1);
       final ThreadGroup group;
       final AtomicInteger threadNumber = new AtomicInteger(1);
       final String namePrefix;

       DefaultThreadFactory() {
           SecurityManager s = System.getSecurityManager();
           group = (s != null)? s.getThreadGroup() :Thread.currentThread().getThreadGroup();
          
           namePrefix = “pool-” + poolNumber.getAndIncrement() + “-thread-“;
       }

       public Thread newThread(Runnable r) {
           Thread t = new Thread(group, r,namePrefix + threadNumber.getAndIncrement(),0);
           if (t.isDaemon())
               t.setDaemon(false);
           if (t.getPriority() != Thread.NORM_PRIORITY)
               t.setPriority(Thread.NORM_PRIORITY);
           return t;
       }
   }


自定义线程工厂ThreadFactory及使用示例:
public class TestExecutorService {

    public static void run(ExecutorService service){
        for(int i = 1;i<5;i++){
            final int taskId = i;
            service.execute(new Runnable() {

                @Override
                public void run() {
                    for(int j = 1;j<5;j++){
                        try {
                            Thread.sleep(1000);
                            System.out.println("当前线程"+Thread.currentThread().getName()+"第"+taskId+"次任务的第"+j+"次执行");
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }

                }
            });
        }
        service.shutdown();
    }
    public static void main(String[] args) {
        ExecutorService service1 = Executors.newCachedThreadPool(new ThreadFactory() {
            private AtomicInteger count = new AtomicInteger(); 
            @Override
            public Thread newThread(Runnable r) {
                 int c = count.incrementAndGet();  
                System.out.println("create num " + c + " Threads"); 
                return new Thread(r,"线程"+c);
            }
        });
        ExecutorService service2 = Executors.newFixedThreadPool(3,new ThreadFactory() {
            private AtomicInteger count = new AtomicInteger(); 
            @Override
            public Thread newThread(Runnable r) {
                 int c = count.incrementAndGet();  
                System.out.println("create num " + c + " Threads"); 
                return new Thread(r,"线程"+c);
            }
        });
        ExecutorService service3 = Executors.newSingleThreadExecutor();
        ExecutorService service4 = Executors.newScheduledThreadPool(3);
        run(service2);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值