java--线程池--创建线程池的几种方式与线程池操作详解

tips:使用junit测试多线程会有问题,建议使用main方法,或在main方法中执行测试方法
·

一、创建线程池与执行任务:ExecutorService接口的Executor实现类

1.普通线程池,使用submit执行

1)创建线程池与执行

newCachedThreadPool / newFixedThreadPool / newSingleThreadExecutor

1.普通创建

  • Executors.newCachedThreadPool()
  • Executors.newCachedThreadPool(ThreadFactory threadFactory) ----可自定义创建线程的代码
    ·

2.指定线程个数

  • Executors.newFixedThreadPool(int threadCount);
  • Executors.newFixedThreadPool(int threadCount, ThreadFactory threadFactory); ----可自定义创建线程的代码
    ·

3.单一线程

  • Executors.newSingleThreadExecutor();
  • Executors.newSingleThreadExecutor(ThreadFactory threadFactory); ----可自定义创建线程的代码

2)代码示例

package threadPool.java;

import org.junit.Test;

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

public class ThreadPoolTest {

    @Test
    public void newCachedThreadPoolTest(){
        // 创建一个线程池,空参构造器
        // ExecutorService executorService = Executors.newCachedThreadPool();
        // 自定义线程创建
        ExecutorService executorService = Executors.newCachedThreadPool(new MyThreadFactory());

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

    @Test
    public void newFixedThreadPoolTest(){
        // 创建一个线程池,指定线程个数
        // ExecutorService executorService = Executors.newFixedThreadPool(3);

        // 自定义创建线程
        ExecutorService executorService = Executors.newFixedThreadPool(3,new MyThreadFactory());

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

    @Test
    public void newSingleThreadExecutorTest(){
        // 创建一个单一线程的线程池
        // ExecutorService executorService = Executors.newSingleThreadExecutor();

        // 自定义创建线程
        ExecutorService executorService = Executors.newSingleThreadExecutor(new MyThreadFactory());

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

}

2.延时与定义执行的线程池,使用schedule执行

1)创建线程池与执行

线程池实例创建:newScheduledThreadPool / newSingleThreadScheduledExecutor,[]表示可选参数

1.指定线程个数

  • ScheduledExecutorService ses = Executors.newScheduledThreadPool(int corePoolSize [, ThreadFactory threadFactory ]);
    ·

2.单一线程

  • ScheduledExecutorService ses = Executors.newSingleThreadScheduledExecutor( [new MyThreadFactory() ])

执行方法说明:

  • ses.schedule(Runnable task,long delay, TimeUnit unit);
    参数分别指定,【任务】,【延时时间(执行schedule之后延时候执行task)】,【时间单位(枚举类)】
    ·
  • ses.scheduleAtFixedRate(Runnable task,long delay, long period, TimeUnit unit);
    参数分别指定,【任务】,【首次延时时间(执行schedule之后延时候执行task)】,【两次任务间隔时间(上一次执行开始到下一次执行开始的时间)】,【时间单位(枚举类)】
    ·
  • ses.scheduleWithFixedDelay(Runnable task,long delay, long period, TimeUnit unit);
    参数分别指定,【任务】,【首次延时时间(执行schedule之后延时候执行task)】,【两次任务间隔时间(上一次执行结束到下一次执行开始的时间)】,【时间单位(枚举类)】

2)代码示例

package threadPool.java;

import org.junit.Test;

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

public class ScheduledThreadPoolTest {
    @Test
    public void scheduleTest(){
        ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(3);
        for (int i = 0; i < 10; i++) {
            scheduledExecutorService.schedule(new Task(i),2, TimeUnit.SECONDS);
        }
        System.out.println("exit");
    }

    @Test
    public void scheduleAtFixedRateTest(){
        ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1,new MyThreadFactory());
        scheduledExecutorService.scheduleAtFixedRate(() -> {
            String str = Thread.currentThread().getName();
            System.out.println(str+"执行开始");
            System.out.println("·");
            try {
                // 任务执行1秒
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(str+"执行结束");
            System.out.println("·");
            System.out.println("·");
            // 初始延迟2秒,以后每次执行任务延迟3秒,上一次执行开始到下一次执行开始的时间为3秒
        }, 2, 3, TimeUnit.SECONDS);
        System.out.println("exit");
    }

    @Test
    public void scheduleWithFixedDelayTest() {
        ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(2,new MyThreadFactory());
        scheduledExecutorService.scheduleWithFixedDelay(new Runnable() {
            @Override
            public void run() {
                String str = Thread.currentThread().getName();
                System.out.println(str+"执行开始");
                System.out.println("·");
                try {
                    // 任务执行1秒
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(str+"执行结束");
                System.out.println("·");
                System.out.println("·");
                System.out.println("·");
                // 初始延迟2秒,以后每次执行任务延迟3秒,上一次执行结束到下一次执行开始的时间为3秒
            }
        }, 2, 3, TimeUnit.SECONDS);
        System.out.println("exit");
    }
    @Test
    public void newSingleThreadScheduledExecutorTest() {
        ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor(new MyThreadFactory());
        scheduledExecutorService.scheduleWithFixedDelay(() -> {
            String str = Thread.currentThread().getName();
            System.out.println(str+"执行开始");
            try {
                // 任务执行1秒
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("执行结束");
            // 初始延迟2秒,以后每次执行任务延迟3秒,上一次执行结束到下一次执行开始的时间为3秒
        }, 2, 3, TimeUnit.SECONDS);
        System.out.println("exit");
    }
    public static void main(String[] args) {
        ScheduledThreadPoolTest scheduledThreadPoolTest = new ScheduledThreadPoolTest();
        // scheduledThreadPoolTest.scheduleWithFixedDelayTest();
        // scheduledThreadPoolTest.scheduleAtFixedRateTest();
         scheduledThreadPoolTest.newSingleThreadScheduledExecutorTest();
    }
}

3.ExecutorService接口的其他操作

1)shutdown()与shutdownNow()


    @Test
    public void shutdownTest(){
        // 创建一个线程池
        ExecutorService executorService = Executors.newFixedThreadPool(5);

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

        // 关闭线程池,返回已提交未执行的任务列表
        List<Runnable> runnables = executorService.shutdownNow();
        System.out.println(runnables);

        // 关闭线程池,在终止前允许执行以前提交的任务
        // executorService.shutdown();
    }

2)submit的返回值

	@Test
    public void operationTest() {
        ExecutorService executorService = Executors.newSingleThreadExecutor();
        // 1.返回一个Future对象
        Future<Integer> future = executorService.submit(new Callable<Integer>() {
            int i = 123;
            int j = 543;
            @Override  // call方法返回值即为Future对象.get()的值
            public Integer call() throws Exception {
                System.out.println("start...");
                Thread.sleep(2000);
                System.out.println("end...");
                return i + j;
            }
        });
        
        // 2.通过future对任务的线程进行操作
        // future.cancel(true);  // 1)取消任务,true任务如果正在执行则中断
        System.out.println(future.isCancelled()); // 2)任务是否取消
        System.out.println(future.isDone()); // 3)任务是否结束
        try {
            Integer result = future.get(); // 4)等待任务执行完成后获取返回值
            System.out.println("result is:"+result);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }

二、线程池的实现原理

参考这篇:Java并发编程:线程池的使用

核心类的构造方法:
在这里插入图片描述
参数解析图:
在这里插入图片描述

三、本文使用到的类

1.MyThreadFactory

package threadPool.java;

import java.util.concurrent.ThreadFactory;

public class MyThreadFactory implements ThreadFactory {
    int taskId=1;
    @Override
    public Thread newThread(Runnable r) {
        return new Thread(r,"Thread-No."+taskId++);
    }
}

2.Task

package threadPool.java;

class Task implements Runnable {
    private int taskId;

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

    @Override
    public void run() {
        String threadName = Thread.currentThread().getName();
        System.out.println(threadName + "任务执行" + taskId);
    }

    @Override
    public String toString() {
        return "No." + taskId;
    }
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

运维小菜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值