创建线程池的几种方式

 使用ThreadPoolExecutor创建线程池

代码案例


/**
 * 线程池使用案例
 * 通过TheadPoolExecutor创建线程池
 * TheadPoolExecutor参数:
 *  corePoolSize: 核心线程数 ,本例中是1
 *  maximumPoolSize: 最大线程数,本列中是3
 *  keepAliveTime: 最大存活时间,本例中是1000
 *  TimeUnit.MILLISECONDS: 最大存活时间的时间单位,本例中是毫秒
 *  存放待处理任务的队列: 这里使用的是LinkedBlockingQueue(2),队列最大长度是2,如果没有参数,则默认是无界队列
 *  线程工厂对象:本例中是new NamedThreadFactory("MyThread"),给线程池命名为"MyThread"
 *  拒绝策略: 这里使用的拒绝策略是CallerRunsPolicy,当队列满了,仍有任务要放入队列时,则调用主线程来处理
 *  因此同时最多只能提交 maximumPoolSize + 队列长度 的任务,本例中是3 + 2 = 5
 *  如果提交任务超过了这个数量,就会启动拒绝策略
 *  在本次案例中,通过输出结果发现,当提交到第6个任务时候,此时超过了 队列长度 + 最大线程数 ,
 *  于是启动了拒绝策略,调用主线程来处理任务
 */
public class ThreadPoolExecutorExample {

    public static void main(String[] args) {
        // 创建一个固定大小为3的线程池
        ThreadPoolExecutor executor = new ThreadPoolExecutor(
                1, 3, 1000,
                TimeUnit.MILLISECONDS,
                new LinkedBlockingQueue<>(2),
                new NamedThreadFactory("MyThread"),
                new ThreadPoolExecutor.CallerRunsPolicy()

        );
        // 提交8个任务给线程池
        for (int i = 1; i <= 8; i++) {
            Task task = new Task("Task " + i);
            System.out.println(LocalTime.now() + " "  + Thread.currentThread() + " 提交任务:" + task.getName());
            executor.execute(task);
        }
        // 关闭线程池
        executor.shutdown();
    }
}

/**
 * 创建任务类,实现Runnable,定义任务
 */
class Task implements Runnable {
    private String name;

    public Task(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    @Override
    public void run() {
        System.out.println(LocalTime.now() + " " + Thread.currentThread().getName() + " 执行任务:" + name);
        try {
            Thread.sleep(2000);   //模拟任务执行时间
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(LocalTime.now() +" " + Thread.currentThread().getName() + " 完成任务:" + name);
    }
}

/**
 * 创建线程工厂,给线程命名
 */
class NamedThreadFactory implements ThreadFactory {
    private String name;

    public NamedThreadFactory(String name) {
        this.name = name;
    }

    @Override
    public Thread newThread(Runnable r) {
        return new Thread(r, name);
    }
}

输出结果

10:50:28.680 Thread[main,5,main] 提交任务:Task 1
10:50:28.681 Thread[main,5,main] 提交任务:Task 2
10:50:28.681 Thread[main,5,main] 提交任务:Task 3
10:50:28.681 Thread[main,5,main] 提交任务:Task 4
10:50:28.681 MyThread 执行任务:Task 1
10:50:28.681 Thread[main,5,main] 提交任务:Task 5
10:50:28.681 MyThread 执行任务:Task 4
10:50:28.681 Thread[main,5,main] 提交任务:Task 6        
10:50:28.681 MyThread 执行任务:Task 5   //此时任务大于队列长度 + 最大线程数量,调用主线程处理任务
10:50:28.681 main 执行任务:Task 6
10:50:30.682 MyThread 完成任务:Task 4
10:50:30.682 main 完成任务:Task 6
10:50:30.682 MyThread 完成任务:Task 1
10:50:30.682 Thread[main,5,main] 提交任务:Task 7
10:50:30.682 MyThread 完成任务:Task 5
10:50:30.682 Thread[main,5,main] 提交任务:Task 8
10:50:30.682 MyThread 执行任务:Task 3
10:50:30.682 MyThread 执行任务:Task 2
10:50:30.682 MyThread 执行任务:Task 7
10:50:32.684 MyThread 完成任务:Task 3
10:50:32.684 MyThread 完成任务:Task 2
10:50:32.684 MyThread 完成任务:Task 7
10:50:32.684 MyThread 执行任务:Task 8
10:50:34.686 MyThread 完成任务:Task 8

 使用Executor工具列创建线程池

Executor工具列创建线程方法

Executors.newFixedThreadPool()

Executors.newSingleThreadExecutor();

Executors.newCachedThreadPool();

Executors.newScheduledThreadPool();

使用newFixedThreadPool()

代码案例

/**
 * 使用newFixedThreadPool(5)创建线程池
 * 该方法创建固定大小的线程数量的线程池
 * 本例中线程池中数量固定为5
 */
public class FixedThreadPoolExample {
    public static void main(String[] args) {
        // 创建一个固定大小的线程池,包含5个线程
        ExecutorService executor = Executors.newFixedThreadPool(5);

        // 提交任务给线程池
        for (int i = 0; i < 10; i++) {
            executor.submit(new Task(i));
        }

        // 关闭线程池
        executor.shutdown();
    }

    static class Task implements Runnable {
        private int taskId;

        public Task(int taskId) {
            this.taskId = taskId;
        }

        @Override
        public void run() {
            try {
                Thread.sleep(2000);  //模拟任务执行时间
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println(LocalDateTime.now().format(DateTimeFormatter.ofPattern("hh:mm:ss")) + " Task " + taskId + " is running on thread " + Thread.currentThread().getName());
        }
    }
}

输出结果

11:05:57 Task 3 is running on thread pool-1-thread-4
11:05:57 Task 2 is running on thread pool-1-thread-3
11:05:57 Task 4 is running on thread pool-1-thread-5
11:05:57 Task 0 is running on thread pool-1-thread-1
11:05:57 Task 1 is running on thread pool-1-thread-2
11:05:59 Task 6 is running on thread pool-1-thread-4
11:05:59 Task 5 is running on thread pool-1-thread-3
11:05:59 Task 7 is running on thread pool-1-thread-5
11:05:59 Task 8 is running on thread pool-1-thread-1
11:05:59 Task 9 is running on thread pool-1-thread-2

使用newSingleThreadExecutor()

代码案例

/**
 * 创建只有一个线程的线程池,
 * 因此本例中提交了10个任务,只能由这一个线程来逐个处理
 */
public class SingleThreadExecutorExample {
    public static void main(String[] args) {
        // 只有一个线程的线程池
        ExecutorService executor = Executors.newSingleThreadExecutor();

        // 提交任务给线程池
        for (int i = 0; i < 10; i++) {
            executor.submit(new SingleThreadExecutorExample.Task(i));
        }

        // 关闭线程池
        executor.shutdown();
    }

    static class Task implements Runnable {
        private int taskId;

        public Task(int taskId) {
            this.taskId = taskId;
        }

        @Override
        public void run() {
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println(LocalDateTime.now().format(DateTimeFormatter.ofPattern("hh:mm:ss")) + " Task " + taskId + " is running on thread " + Thread.currentThread().getName());
        }
    }
}

输出结果

11:08:34 Task 0 is running on thread pool-1-thread-1
11:08:37 Task 1 is running on thread pool-1-thread-1
11:08:39 Task 2 is running on thread pool-1-thread-1
11:08:41 Task 3 is running on thread pool-1-thread-1
11:08:43 Task 4 is running on thread pool-1-thread-1
11:08:45 Task 5 is running on thread pool-1-thread-1
11:08:47 Task 6 is running on thread pool-1-thread-1
11:08:49 Task 7 is running on thread pool-1-thread-1
11:08:51 Task 8 is running on thread pool-1-thread-1
11:08:53 Task 9 is running on thread pool-1-thread-1

使用newCachedThreadPool()

代码案例

/**
 * newCachedThreadPool()创建一个根据提交任务数量,动态调整线程数量的线程池
 * 通过输出结果发现10个任务在同一时间被处理
 */
public class CachedThreadPoolExample {
    public static void main(String[] args) {
        // 创建一个根据任务数量动态调整的线程池
        ExecutorService executor = Executors.newCachedThreadPool();

        // 提交任务给线程池
        for (int i = 0; i < 10; i++) {
            executor.submit(new CachedThreadPoolExample.Task(i));
        }

        // 关闭线程池
        executor.shutdown();
    }

    static class Task implements Runnable {
        private int taskId;

        public Task(int taskId) {
            this.taskId = taskId;
        }

        @Override
        public void run() {
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println(LocalDateTime.now().format(DateTimeFormatter.ofPattern("hh:mm:ss")) + " Task " + taskId + " is running on thread " + Thread.currentThread().getName());
        }
    }
}

输出结果 

11:16:15 Task 3 is running on thread pool-1-thread-4
11:16:15 Task 5 is running on thread pool-1-thread-6
11:16:15 Task 8 is running on thread pool-1-thread-9
11:16:15 Task 9 is running on thread pool-1-thread-10
11:16:15 Task 2 is running on thread pool-1-thread-3
11:16:15 Task 6 is running on thread pool-1-thread-7
11:16:15 Task 4 is running on thread pool-1-thread-5
11:16:15 Task 0 is running on thread pool-1-thread-1
11:16:15 Task 7 is running on thread pool-1-thread-8
11:16:15 Task 1 is running on thread pool-1-thread-2

使用newScheduledThreadPool()

代码案例

/**
 * newScheduledThreadPool()创建延迟处理任务的线程池,可以设置核心线程数,本例中为3
 * 调用schedule可以指定延迟处理的时间,处理任务的周期
 */
public class ScheduledThreadPoolExample {
    public static void main(String[] args) {
        ScheduledExecutorService executor = Executors.newScheduledThreadPool(3);


        // 延迟1秒后执行任务
        executor.schedule(new Task("Task 1"), 1, TimeUnit.SECONDS);

        // 每隔2秒执行一次任务
        executor.scheduleAtFixedRate(new Task("Task 2"), 0, 2, TimeUnit.SECONDS);

        // 延迟3秒后开始执行,然后每隔5秒执行一次任务
        executor.scheduleWithFixedDelay(new Task("Task 3"), 3, 5, TimeUnit.SECONDS);
    }

    static class Task implements Runnable {
        private String taskName;

        public Task(String taskName) {
            this.taskName = taskName;
        }

        @Override
        public void run() {
            System.out.println(LocalDateTime.now().format(DateTimeFormatter.ofPattern("hh:mm:ss")) + " " + taskName + " is running on thread " + Thread.currentThread().getName());
        }
    }
}

输出结果

本例输出结果为持续输出,这里只截取一部分输出结果

11:25:23 Task 2 is running on thread pool-1-thread-1
11:25:24 Task 1 is running on thread pool-1-thread-2
11:25:25 Task 2 is running on thread pool-1-thread-3
11:25:26 Task 3 is running on thread pool-1-thread-1
11:25:27 Task 2 is running on thread pool-1-thread-2
11:25:29 Task 2 is running on thread pool-1-thread-2
11:25:31 Task 2 is running on thread pool-1-thread-3
11:25:31 Task 3 is running on thread pool-1-thread-2
11:25:33 Task 2 is running on thread pool-1-thread-3
11:25:35 Task 2 is running on thread pool-1-thread-3
11:25:36 Task 3 is running on thread pool-1-thread-1

你可能感兴趣的:(Java并发编程,java,开发语言)