Executors :

Executors ,就是一个线程工具类;大部分操作线程的方法,都可以在这个工具类中就行创建,执行,调用一些线程的方法;

Executor :

用于执行和提交一个runnable 任务;就是将线程的创建与执行就行了解藕:
像:
new Thread(new(RunnableTask())).start()} 
可以被替代为
Executor executor = anExecutor;
executor.execute(new RunnableTask1());:

线程池 ThreadPool:

是我们维护线程数量的一个池子,创建的目的是为了节省系统资源,避免频繁创建线程与销毁线程带来的系统开销;接下来进行实例型的线程例子:

 

1. Executors.newFixedThreadPool(nthread); 创建一个固定数量的线程池

如果任务超出了线程的数量,那么多出的任务放在 LinkedBlockingQueue<Runnable>中,然后在这个队列中进行进行任务获取执行,先进先出;

尝试运行如下程序:

    public static void main(String[] args) throws InterruptedException {
        
        ExecutorService pool = Executors.newFixedThreadPool(3);
    
        for(int i=0;i<6;i++) {
            pool.submit(()->{
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName()+"....");});
        }
        System.out.println(pool.isTerminated());
        System.out.println(pool);
        Thread.sleep(4000);
        System.err.println(pool);
        pool.shutdown();            
    }

 运行结果如下:

false
java.util.concurrent.ThreadPoolExecutor@eed1f14[Running, pool size = 3, active threads = 3, queued tasks = 3, completed tasks = 0]
pool-1-thread-1....
pool-1-thread-3....
pool-1-thread-2....
pool-1-thread-3....
pool-1-thread-1....
pool-1-thread-2....
java.util.concurrent.ThreadPoolExecutor@eed1f14[Running, pool size = 3, active threads = 0, queued tasks = 0, completed tasks = 6]

可以看到我们的线程池对象中

pool size :大小就是我们定义的3个线程,且运行也是在这3个线程之内进行运行;

active thread:目前活动的线程

queued tasks :在队列中的线程数量

completed tasks :完成的线程数

运作机制:在 ThreadPoolExecutor类中维护着一个worker内部类的内部类来维护着线程的运行状态;

        volatile long completedTasks;//统计已经执行完毕的线程数量
    //可以看到使用了线程工厂ThreadFactory进行线程的创建,我们所有的任务都会在这里进行工作的分配
        Worker(Runnable firstTask) {
            setState(-1); // inhibit interrupts until runWorker
            this.firstTask = firstTask;
            this.thread = getThreadFactory().newThread(this);
        }

        /** Delegates main run loop to outer runWorker  */
        public void run() {
            runWorker(this);
        }

2.Executors.newCachedThreadPool() 创建缓存线程池;

    public static void main(String[] args) throws InterruptedException, ExecutionException {
    
        ExecutorService pool = Executors.newCachedThreadPool();
        
        Future<Integer> p1 = pool.submit(()->{ Thread.sleep(1000);System.out.println(Thread.currentThread().getName());return 2;});
        Future<Integer> p2 = pool.submit(()->{ Thread.sleep(1000); System.out.println(Thread.currentThread().getName());return 3;});
        Future<Integer> p3 = pool.submit(()->{ Thread.sleep(1000); System.out.println(Thread.currentThread().getName());return 4;});
        Future<Integer> p4 = pool.submit(()->{ System.out.println(Thread.currentThread().getName());return 5;});
        Future<Integer> p5 = pool.submit(()->{ System.out.println(Thread.currentThread().getName());return 6;});
        Future<Integer> p6 = pool.submit(()->{ System.out.println(Thread.currentThread().getName());return 8;});
        System.out.println(pool);
        Thread.sleep(70000);
        System.err.println(pool);
        
    }

结果如下:

pool-1-thread-4
pool-1-thread-5
pool-1-thread-5
java.util.concurrent.ThreadPoolExecutor@41629346[Running, pool size = 5, active threads = 3, queued tasks = 0, completed tasks = 3]
pool-1-thread-1
pool-1-thread-2
pool-1-thread-3
java.util.concurrent.ThreadPoolExecutor@41629346[Running, pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 6]

 得知CacheThreadPool会根据任务来创建不同个数的线程;没有空闲的线程就创建;有就重复使用

 最大是integet.MAX_VALUE,线程超过60second 不使用,线程会被销毁;应用于并发很大,机器很牛逼;

3.Executors.newSingleThreadExecutor() :创建一个单个线程;顾名思义:就是所有的任务都放在一个线程中去执行,这样就保证了线程中任务运行的执行顺序,按照顺序进行执行;

 

public static void main(String[] args) {
        
        ExecutorService pool = Executors.newSingleThreadExecutor();
        

        Future<Integer> p1 = pool.submit(()->{ Thread.sleep(1000);System.out.println(Thread.currentThread().getName()+"...1");return 2;});
        Future<Integer> p2 = pool.submit(()->{ Thread.sleep(1000); System.out.println(Thread.currentThread().getName()+"...2");return 3;});
        Future<Integer> p3 = pool.submit(()->{ Thread.sleep(1000); System.out.println(Thread.currentThread().getName()+"...3");return 4;});
        Future<Integer> p4 = pool.submit(()->{ System.out.println(Thread.currentThread().getName()+"...4");return 5;});
        Future<Integer> p5 = pool.submit(()->{ System.out.println(Thread.currentThread().getName()+"...5");return 6;});
        Future<Integer> p6 = pool.submit(()->{ System.out.println(Thread.currentThread().getName()+"...6");return 8;});
        System.out.println(pool);
        
    }

可以看到任务都是一条一条执行的;

4.Executors.newScheduledThreadPool(nthread) :用来执行定时任务的线程池,代替了timer

public static void main(String[] args) throws Exception{
        
        ScheduledExecutorService schedule = Executors.newScheduledThreadPool(2);
        //在指定时间内执行,只执行一次
        ScheduledFuture<Integer> schedule2 = schedule.schedule(()-> {System.out.println(Thread.currentThread().getName());return  2;}, 3, TimeUnit.SECONDS);
        
        //指定时间时间,并在一定的时间内去重复执行
        schedule.scheduleAtFixedRate(()->{System.out.println(Thread.currentThread().getName());}, 1, 3, TimeUnit.SECONDS);
        System.out.println(schedule);
        Thread.sleep(10000);
        System.out.println(schedule);
}

 5. ForkJoinPool:可以将一个庞大的任务根据自己的规则将任务划分成不同的小块,ForkJoin会根据规则去开启线程去运行每一个小部分;

例子是计算0-2000000的和:使用extends  RecursiveAction 这个没有返回值;

package com.java.baseknowledge.concurrent15;

import java.io.IOException;
import java.util.Random;
import java.util.concurrent.Executors;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveAction;

/**
 * fork join pool
 * 进行将一个大的任务根据自己的规则进行切分,用线程去执行
 * 启动的线程是后台线程(精灵线程🧚‍♀️),
 * 
 * @author iscys
 *
 */
public class ThreadPool8 {
    static int isFork=50000;
    static int [] ar =new int[2000000];
static {
    for(int i=0;i<ar.length;i++) {ar[i]=new Random().nextInt(10);}
    
}
    
    public static void main(String[] args) throws IOException {
        
        
        ForkJoinPool fp =new ForkJoinPool();
        //执行ForkJoinTask任务
        fp.submit(new ForkTask(0,ar.length));
        System.in.read();
    }
    
    
    
    
    static class ForkTask extends RecursiveAction{
        //根据规则去划分任务,一致进行切分;
        private int start,end;
        ForkTask(int st,int end){this.start=st;this.end=end;}
        @Override
        protected void compute() {
            if(end-start<=isFork) {
                long sum =0l;
                for(int i=start ;i<end;i++) {
                    sum+=ar[i];
                }
                System.out.println(Thread.currentThread().getName()+"from --"+start+"to--"+end+"sum="+sum);
            }
            else {
          //划分任务
int middle=start+(end-start)/2; ForkTask forkTask = new ForkTask(start,middle); ForkTask forkTask2 = new ForkTask(middle,end); forkTask.fork(); forkTask2.fork(); } } } }

 

 使用 extends RecursiveTask<Long> 这个有返回值,fork() 拆任务  join()计算任务总和

package com.java.baseknowledge.concurrent15;

import java.io.IOException;
import java.util.Arrays;
import java.util.Random;
import java.util.concurrent.Executors;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveAction;
import java.util.concurrent.RecursiveTask;

/**
 * fork join pool
 * 进行将一个大的任务根据自己的规则进行切分,用线程去执行
 * 启动的线程是后台线程(精灵线程🧚‍♀️),
 * 
 * @author iscys
 *
 */
public class ThreadPool8 {
    static int isFork=50000;
    static int [] ar =new int[2000000];
static {
    for(int i=0;i<ar.length;i++) {ar[i]=new Random().nextInt(10);}
    
}
    
    public static void main(String[] args) throws IOException {
        
        System.out.println(Arrays.stream(ar).sum());
        ForkJoinPool fp =new ForkJoinPool();
        //执行ForkJoinTask任务
        ForkTask forkTask = new ForkTask(0,ar.length);
        fp.submit(forkTask);
        Long join = forkTask.join();
        System.out.println(join);
        
    }
    
    
    
    static class ForkTask extends RecursiveTask<Long>{
        //根据规则去划分任务,一致进行切分;
        private int start,end;
        ForkTask(int st,int end){this.start=st;this.end=end;}
        protected Long compute() {
            if(end-start<=isFork) {
                long sum =0l;
                for(int i=start ;i<end;i++) {
                    sum+=ar[i];
                }
                System.out.println(Thread.currentThread().getName()+"from --"+start+"to--"+end+"sum="+sum);
                return sum;
            }
            else {
                int middle=start+(end-start)/2;
                ForkTask forkTask = new ForkTask(start,middle);
                ForkTask forkTask2 = new ForkTask(middle,end);
                forkTask.fork();
                forkTask2.fork();
                return forkTask.join()+forkTask2.join();
            }
            
            
        }
        
    }
}

 

 

 

 

 

 

posted on 2018-09-28 23:17  iscys  阅读(212)  评论(0编辑  收藏  举报