实战Java高并发程序设计-05 Java并发包线程池

概念

线程的创建与销毁都需要销毁资源,为了避免频繁的创建与销毁线程,可以让创建的线程进行复用。类似数据库连接池的概念,

Java中的线程池

Java通过Executors提供四种线程池,分别为:
newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。
newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。

缓存线程池(CachedThreadPool )

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ThreadPoolExecutorTest {
    public static void main(String[] args) {
        ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
        for (int i = 0; i < 10; i++) {
            final int index = i;
            try {
                Thread.sleep(index * 1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            cachedThreadPool.execute(new Runnable() {
                public void run() {
                    System.out.println(Thread.currentThread().getId() + " : " + index);
                }
            });
        }
        cachedThreadPool.shutdown();
    }
}

打印结果发现 执行上一个线程处理的过来打印,所以都是同一个线程完成任务.

9 : 0
9 : 1
9 : 2
9 : 3
9 : 4
9 : 5
9 : 6
9 : 7
9 : 8
9 : 9
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ThreadPoolExecutorTest {
    public static void main(String[] args) {
        ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
        for (int i = 0; i < 10; i++) {
            final int index = i;
            cachedThreadPool.execute(new Runnable() {
                public void run() {
                    System.out.println(Thread.currentThread().getId() + " : " + index);
                }
            });
        }
        cachedThreadPool.shutdown();
    }
}

打印结果,发现当前线程池的线程处理不过来,自动创建新的线程来做处理

9 : 0
12 : 3
10 : 1
11 : 2
14 : 5
15 : 6
13 : 4
16 : 7
14 : 8
16 : 9

定长线程池(FixedThreadPool)

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ThreadPoolExecutorTest {
    public static void main(String[] args) {
        ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);
        for (int i = 0; i < 10; i++) {
            final int index = i;
            fixedThreadPool.execute(new Runnable() {
                public void run() {
                    try {
                        System.out.println(Thread.currentThread().getId() + " : " + index);
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
        }
        fixedThreadPool.shutdown();
    }
}

打印结果 始终只有三个线程处理,没有来得及处理的排队等待

9 : 0
10 : 1
11 : 2
10 : 3
11 : 5
9 : 4
11 : 6
9 : 8
10 : 7
10 : 9

调度计划线程池(ScheduledThreadPool)

三秒钟之后开始执行,执行完毕就关闭,不循环

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class ThreadPoolExecutorTest {
    public static void main(String[] args) {
        //三秒后执行
        ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);
        scheduledThreadPool.schedule(new Runnable() {
            public void run() {
                System.out.println("delay 3 seconds");
            }
        }, 3, TimeUnit.SECONDS);

        scheduledThreadPool.shutdown();
    }
}
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class ThreadPoolExecutorTest {
    public static void main(String[] args) {
        ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(10);
        scheduledThreadPool.scheduleAtFixedRate(new Runnable() {
            public void run() {
                System.out.println(Thread.currentThread().getId() + " : delay 3 seconds, and excute every 2 seconds");
            }
        }, 3, 2, TimeUnit.SECONDS);
    }
}

打印结果: 三秒后开始执行打印,之后没两秒执行一次,不断轮询,每次执行的线程不固定

9 : delay 3 seconds, and excute every 2 seconds
9 : delay 3 seconds, and excute every 2 seconds
11 : delay 3 seconds, and excute every 2 seconds
9 : delay 3 seconds, and excute every 2 seconds
12 : delay 3 seconds, and excute every 2 seconds
11 : delay 3 seconds, and excute every 2 seconds
13 : delay 3 seconds, and excute every 2 seconds
9 : delay 3 seconds, and excute every 2 seconds

单线程线程池(SingleThreadExecutor)

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ThreadPoolExecutorTest {
    public static void main(String[] args) {
        ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
        for (int i = 0; i < 20; i++) {
            final int index = i;
            singleThreadExecutor.execute(new Runnable() {
                public void run() {
                    try {
                        System.out.println(Thread.currentThread().getId() + " : " + index);
                        Thread.sleep(20);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
        }
    }
}

打印结果: 发现每次都是同一个线程执行

9 : 0
9 : 1
9 : 2
9 : 3
9 : 4
9 : 5
9 : 6
9 : 7
9 : 8
9 : 9
9 : 10
9 : 11
9 : 12
9 : 13
9 : 14
9 : 15
9 : 16
9 : 17
9 : 18
9 : 19

自定义线程池(ThreadPoolExecutor)

说明

上面四种线程池除了(ScheduledThreadPool)外都继承与ThreadPoolExecutor类,只不过传递的参数不同而已.

这里写图片描述

这里写图片描述

这里写图片描述
ThreadPoolExecutor的构造函数如下

corePoolSize:指定线程池中线程数量
maximumPoolSize : 指定线程池中最大线程数
keepAliveTime : 当线程池线程数量超过corePoolSize时,多余的空闲线程存活时间.
unit : keepAliveTime 参数的单位
workQueue : 任务队列,被加入进来执行的任务,但是未被执行的任务队列


 public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue) {

自定义线程池

上面既然发现jdk提供的线程池来自于ThreadPoolExecutor,
那么一样可以自定义

ExecutorService singleThreadExecutor = new ThreadPoolExecutor(10, 10, 0, TimeUnit.DAYS, 
                new LinkedBlockingQueue<Runnable>(),new ThreadFactory() {

            @Override
            public Thread newThread(Runnable r) {
                Thread t = new Thread(r);
                return t;
            }
        });

扩展线程池

执行之前,结束之后,终止调用的方法.


        ExecutorService es = new ThreadPoolExecutor(10, 10, 0, TimeUnit.DAYS, new LinkedBlockingQueue<Runnable>()){

            @Override
            protected void beforeExecute(Thread t, Runnable r) {
                super.beforeExecute(t, r);
            }

            @Override
            protected void afterExecute(Runnable r, Throwable t) {
                super.afterExecute(r, t);
            }

            @Override
            protected void terminated() {
                super.terminated();
            }

        };
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章