Java线程池介绍与基本案例

Java线程池

线程池的概念:首先创建一些线程,他们的集合成为线程池,当服务器接收到一个客户请求后,就从线程池中取出一个空闲的线程为之服务,服务完后不关闭该线程,而是将线程还到线程池中。
线程池的两个主要作用:
控制线程数量(避免因为创建大量的线程导致的系统崩溃)
重用线程(避免频繁地创建销毁线程)

1.
Callable 内有个 call方法可以有返回值 Runnable run方法无返回值
ExecutorService 接口继承与Executor submit方法独有返回Future
Executors 操作Executor工具类

2. ThreadPool (Executors.newFixedThreadPool(5))

public class T05_ThreadPool {
  public static void main(String[] args) throws InterruptedException {
     //创建固定大小的线程池
     ExecutorService fixedThreadPool = Executors.newFixedThreadPool(5);
        for (int i = 0; i <= 5; i++){
            fixedThreadPool.execute(() -> {try {TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {e.printStackTrace();}
                System.out.println("当前运行的线程:"+ Thread.currentThread().getName());
            });   }
        System.out.println(fixedThreadPool);
        fixedThreadPool.shutdown();
        System.out.println(fixedThreadPool.isTerminated());
        System.out.println(fixedThreadPool.isShutdown());
        TimeUnit.SECONDS.sleep(5);
        System.out.println(fixedThreadPool.isTerminated());
        System.out.println(fixedThreadPool.isShutdown());
        System.out.println(fixedThreadPool);       }}

3. FutureTaskPool

public class T06_FutureTaskPool {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        FutureTask futureTask = new FutureTask(() -> {
            TimeUnit.MILLISECONDS.sleep(500);
            return 10086;});  //内部是Callable中call方法
        new Thread(futureTask).start(); //启动线程
        System.out.println(futureTask.get()); //该方法是一个阻塞方法 执行结束该线程才完成
        System.out.println("***************************************");
        //创建线程池
        ExecutorService fixedThreadPool = Executors.newFixedThreadPool(5);
        Future submit = fixedThreadPool.submit(() -> {
            TimeUnit.MILLISECONDS.sleep(500);
            return 10010;});
        fixedThreadPool.shutdown();
        System.out.println(submit.get());
        System.out.println(submit.isDone());
        System.out.println(submit.isCancelled());     }}

4. ParallelComputing //并行执行

public class T07_ParallelComputing {
    //计算1000000以内的质数
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        long start = System.currentTimeMillis();
        ArrayList integers = get(1, 1000000);
        long end = System.currentTimeMillis();
        System.out.println(end - start);
        //创建Callable线程实现
        MyTask myTask = new MyTask(1, 20000);
        MyTask myTask1 = new MyTask(200001, 400000);
        MyTask myTask2 = new MyTask(400001, 600000);
        MyTask myTask3 = new MyTask(600001, 800000);
        MyTask myTask4 = new MyTask(800001, 1000000);

        ExecutorService pool = Executors.newFixedThreadPool(5);
        Future> submit = pool.submit(myTask);
        Future> submit1 = pool.submit(myTask1);
        Future> submit2 = pool.submit(myTask2);
        Future> submit3 = pool.submit(myTask3);
        Future> submit4 = pool.submit(myTask4);
        start = System.currentTimeMillis();
        submit.get();
        submit1.get();
        submit2.get();
        submit3.get();
        submit4.get();
        end = System.currentTimeMillis();
        System.out.println(end - start);
        pool.shutdown();   }
    static class MyTask implements Callable> {
        int start, end;
        public MyTask(int start, int end) {
            this.start = start;
            this.end = end;    }
     @Override
     public List call() throws Exception {
            return get(start, end);} }
     public static boolean isPrime(int num) {
        for (int i = 2; i <= num / 2; i++)
            if (num % 2 == 0) return false;
        return true;}
    public static ArrayList get(int start, int end) {
        ArrayList arrayList = new ArrayList<>();
        for (int i = start; i <= end; i++) {
            if (isPrime(i)) arrayList.add(i);  }
        return arrayList;    }}

5. CachedPool
缓存线程池(Executors.newCachedThreadPool()),当有任务来线程池无空闲线程就会创建(默认无上限),但可以设置,默认当执行完的线程空闲60S自动关闭

public class T08_CachedPool {
    public static void main(String[] args) throws InterruptedException {
        ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
        System.out.println(cachedThreadPool);
   for (int i = 0; i < 3; i++) 
   {cachedThreadPool.execute(() -> System.out.println(Thread.currentThread().getName())); }
        System.out.println(cachedThreadPool);
        TimeUnit.SECONDS.sleep(70);
        System.out.println(cachedThreadPool);
        cachedThreadPool.shutdown(); }}

6. SinglePool (Executors.newSingleThreadExecutor()) 线程池内就一个线程

7.ScheduledPool (Executors.newScheduledThreadPool(3))

public class T10_ScheduledPool {
    public static void main(String[] args) {
        ScheduledExecutorService pool = Executors.newScheduledThreadPool(3);
 //定时执行的线程池,有四个参数:接口,初始延迟,执行期间,时间单位
        pool.scheduleAtFixedRate(() -> {
        try { TimeUnit.MILLISECONDS.sleep(new Random().nextInt(100));
            } catch (InterruptedException e) {e.printStackTrace();}
            System.out.println(Thread.currentThread().getName());
        },0,300, TimeUnit.MILLISECONDS);    }
}

8.WorkStealingPool (Executors.newWorkStealingPool()) 窃取
该线程池,每个线程都维护自己的任务队列,当执行完自己队列里面的线程 会去偷其他线程内的任务执行
可以传int 参数,默认不传根据CPU核数启动线程数
这是个精灵线程 daemo,内部是封装的 ForkJoinPool

9. ForkJoinPool 下面两个都是递归的思想 进行拆分
RecursiveAction //无返回值
RecursiveTask //有返回值
[例子如下 T12_ForkJoinPool ]
public class T12_ForkJoinPool {

static int[] nums = new int[100000];
static int maxNum = 5000;
static Random random = new Random();
static {
    //初始化数组
    for (int i = 0; i < nums.length; i++) nums[i] = random.nextInt(100);
    System.out.println(Arrays.stream(nums).sum());
}
public static void main(String[] args) throws Exception {
   ForkJoinPool joinPool = new ForkJoinPool();
    /* MyTask task = new MyTask(0, nums.length);
    joinPool.execute(task);  //无返回值
    System.out.println("*******************************");
    */
    MyTask2 task2 = new MyTask2(0, nums.length);
    ForkJoinTask joinTask = joinPool.submit(task2);
    System.out.println(joinTask.get());  //有返回值
    joinPool.shutdown();
    //System.in.read();  //因为是守护线程会在后台运行
}

static class MyTask extends RecursiveAction {
    int start, end;
    public MyTask(int start, int end) {
        this.start = start;
        this.end = end;       }
    @Override
    protected void compute() {
        //递归切分逻辑
        if (end - start <= 5000) {
            long sum = 0;
            for (int i = start; i < end; i++) sum += nums[i];
            System.out.println("start:" + start + " end:" + end + " sum:" + sum);
        } else {
            int middle = start + (end - start) / 2;
            MyTask task1 = new MyTask(start, middle);
            MyTask task2 = new MyTask(middle, end);
            task1.fork();
            task2.fork();     }}}
static class MyTask2 extends RecursiveTask {
    int start, end;
    public MyTask2(int start, int end) {
        this.start = start;
        this.end = end;
    }
    @Override
    protected Long compute() {
        //递归切分逻辑
        if (end - start <= 5000) {
            long sum = 0;
            for (int i = start; i < end; i++) sum += nums[i];
            return sum;  } 
        else {
            int middle = start + (end - start) / 2;
            MyTask2 task1 = new MyTask2(start, middle);
            MyTask2 task2 = new MyTask2(middle, end);
            task1.fork();
            task2.fork();
            return task1.join() + task2.join();    }}}}

你可能感兴趣的:(Java,线程池)