《多线程创建与使用、线程池、异步编排任务》

文章目录

  • 一、多线程创建
    • 继承Thread类
    • 实现Runnable接口
    • 实现Callable接口
  • 二、线程优先级
  • 三、线程同步
    • 同步方法
    • 同步代码块
    • 深入理解synchronized底层原理
  • 四、死锁
  • 五、线程池
    • 线程池说明
    • Bean方式创建异步线程池
    • 可缓存线程池:newCachedThreadPool
    • 定长线程池:newFixedThreadPool
    • 定时及周期性任务执行:newScheduledThreadPool
    • 单线程化的线程池:newSingleThreadExecutor
  • 六、线程池源码
    • 线程池核心属性
    • 线程池状态变化
    • 创建线程池流程
  • 七、使用线程池异步编排任务
    • 配置线程池
    • 异步编排任务

一、多线程创建

继承Thread类

《多线程创建与使用、线程池、异步编排任务》_第1张图片
《多线程创建与使用、线程池、异步编排任务》_第2张图片
《多线程创建与使用、线程池、异步编排任务》_第3张图片
《多线程创建与使用、线程池、异步编排任务》_第4张图片

实现Runnable接口

《多线程创建与使用、线程池、异步编排任务》_第5张图片
《多线程创建与使用、线程池、异步编排任务》_第6张图片
《多线程创建与使用、线程池、异步编排任务》_第7张图片

实现Callable接口

《多线程创建与使用、线程池、异步编排任务》_第8张图片
《多线程创建与使用、线程池、异步编排任务》_第9张图片
《多线程创建与使用、线程池、异步编排任务》_第10张图片

《多线程创建与使用、线程池、异步编排任务》_第11张图片

二、线程优先级

《多线程创建与使用、线程池、异步编排任务》_第12张图片
《多线程创建与使用、线程池、异步编排任务》_第13张图片

三、线程同步

同步方法

《多线程创建与使用、线程池、异步编排任务》_第14张图片
《多线程创建与使用、线程池、异步编排任务》_第15张图片

同步代码块

《多线程创建与使用、线程池、异步编排任务》_第16张图片

《多线程创建与使用、线程池、异步编排任务》_第17张图片
《多线程创建与使用、线程池、异步编排任务》_第18张图片

深入理解synchronized底层原理

深入理解synchronized底层原理,一篇文章就够了!

四、死锁

《多线程创建与使用、线程池、异步编排任务》_第19张图片

五、线程池

Java通过Executors提供四种线程池,分别为:

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

https://blog.csdn.net/u011974987/article/details/51027795


线程池说明

《多线程创建与使用、线程池、异步编排任务》_第20张图片

《多线程创建与使用、线程池、异步编排任务》_第21张图片


Bean方式创建异步线程池

1、配置

@Configuration
@EnableAsync
public class TaskPoolConfig {

    @Bean("taskExecutor")
    public Executor taskExecutro(){
        ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
        taskExecutor.setCorePoolSize(10);
        taskExecutor.setMaxPoolSize(50);
        taskExecutor.setQueueCapacity(200);
        taskExecutor.setKeepAliveSeconds(60);
        taskExecutor.setThreadNamePrefix("taskExecutor--");
        taskExecutor.setWaitForTasksToCompleteOnShutdown(true);
        taskExecutor.setAwaitTerminationSeconds(60);
        return taskExecutor;
    }
}

springBoot启动类的配置

在Spring Boot的主程序中配置@EnableAsync,如下所示:

@ServletComponentScan  
@SpringBootApplication  
@EnableAsync  
public class ClubApiApplication {  
    public static void main(String[] args) {  
        SpringApplication.run(ClubApiApplication.class, args);  
    }  
}  

2、使用

@Component
public class AsyncTask {

    @Async("taskExecutor")
    public void tesTask(int i){
        System.out.println(Thread.currentThread().getName()+"-----"+i);
    }

    @Async("taskExecutor")
    public void stringTask(String str){
       System.out.println(Thread.currentThread().getName()+str);
    }
}

可缓存线程池:newCachedThreadPool

创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。示例代码如下:

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() {
		@Override
		public void run() {
		    System.out.println(index);
		}
	});
}

线程池为无限大,当执行第二个任务时第一个任务已经完成,会复用执行第一个任务的线程,而不用每次新建线程。

定长线程池:newFixedThreadPool

创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。示例代码如下:

《多线程创建与使用、线程池、异步编排任务》_第22张图片
结果:
《多线程创建与使用、线程池、异步编排任务》_第23张图片

从以上结果可以看出,newFixedThreadPool的参数指定了可以运行的线程的最大数目,超过这个数目的线程加进去以后,不会运行。其次,加入线程池的线程属于托管状态,线程的运行不受加入顺序的影响。

定时及周期性任务执行:newScheduledThreadPool

创建一个定长线程池,支持定时及周期性任务执行。延迟执行示例代码如下:

ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);
 scheduledThreadPool.schedule(new Runnable() {

@Override
public void run() {
    System.out.println("delay 3 seconds");
}
}, 3, TimeUnit.SECONDS);

表示延迟3秒执行。

定期执行示例代码如下:


scheduledThreadPool.scheduleAtFixedRate(new Runnable() {

@Override
public void run() {
    System.out.println("delay 1 seconds, and excute every 3 seconds");
}
}, 1, 3, TimeUnit.SECONDS);

表示延迟1秒后每3秒执行一次。

ScheduledExecutorService比Timer更安全,功能更强大

单线程化的线程池:newSingleThreadExecutor

创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。示例代码如下:

ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
for (int i = 0; i < 10; i++) {
final int index = i;
singleThreadExecutor.execute(new Runnable() {

@Override
public void run() {
    try {
        System.out.println(index);
    Thread.sleep(2000);
} catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
        }
}
    });
}

结果依次输出,相当于顺序执行各个任务。

现行大多数GUI程序都是单线程的。Android中单线程可用于数据库操作,文件操作,应用批量安装,应用批量删除等不适合并发但可能IO阻塞性及影响UI线程响应的操作。

六、线程池源码

线程池核心属性

《多线程创建与使用、线程池、异步编排任务》_第24张图片

线程池状态变化

《多线程创建与使用、线程池、异步编排任务》_第25张图片

创建线程池流程

《多线程创建与使用、线程池、异步编排任务》_第26张图片

execute

《多线程创建与使用、线程池、异步编排任务》_第27张图片
《多线程创建与使用、线程池、异步编排任务》_第28张图片
addWorker

《多线程创建与使用、线程池、异步编排任务》_第29张图片
《多线程创建与使用、线程池、异步编排任务》_第30张图片
《多线程创建与使用、线程池、异步编排任务》_第31张图片
《多线程创建与使用、线程池、异步编排任务》_第32张图片
《多线程创建与使用、线程池、异步编排任务》_第33张图片

Worker

《多线程创建与使用、线程池、异步编排任务》_第34张图片

runWorker
《多线程创建与使用、线程池、异步编排任务》_第35张图片
《多线程创建与使用、线程池、异步编排任务》_第36张图片

七、使用线程池异步编排任务

配置线程池

在配置文件配置信息

#线程池配置
my.thread.core-size=20
my.thread.max-size=200
my.thread.keep-alive-time=10

配置线程池

《多线程创建与使用、线程池、异步编排任务》_第37张图片

@Configuration
public class MyThreadConfig {

    @Value("${my.thread.core-size}")
    private int corePoolSize;

    @Value("${my.thread.max-size}")
    private int maxPoolSize;

    @Value("${my.thread.keep-alive-time}")
    private long keepAliveTime;

    //配置线程池
    public ThreadPoolExecutor threadPoolExecutor(){
        return new ThreadPoolExecutor(corePoolSize,
                maxPoolSize,
                keepAliveTime,
                TimeUnit.SECONDS,
                new LinkedBlockingDeque<>(100000),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy());
    }
}

异步编排任务

《多线程创建与使用、线程池、异步编排任务》_第38张图片

public class ThreadPool {

    public static ExecutorService executor = Executors.newFixedThreadPool(5);

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        CompletableFuture<Void> future111 = CompletableFuture.supplyAsync( () -> {
            System.out.println("111");
            return null;
        },executor);

        CompletableFuture<Void> future333 = future111.thenAcceptAsync((res) -> {
            System.out.println("333");
        }, executor);

        CompletableFuture<Void> future444 = future111.thenAcceptAsync((res) -> {
            System.out.println("444");
        }, executor);

        CompletableFuture<Void> future222 = CompletableFuture.supplyAsync( () -> {
            System.out.println("222");
            return null;
        },executor);

        CompletableFuture.allOf(future333,future444,future222).get();
    }
}

《多线程创建与使用、线程池、异步编排任务》_第39张图片

你可能感兴趣的:(技能学习,多线程,线程池)