多线程 之 线程池1

Posted 健康平安的活着

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多线程 之 线程池1相关的知识,希望对你有一定的参考价值。

一 线程池

1.1 概念

线程池(英语:thread pool):一种线程使用模式。线程过多会带来调度开销,进而影响缓存局部性和整体性能。而线程池维护着多个线程,等待着监督管理者分配可并发执行的任务。这避免了在处理短时间任务时创建与销毁线程的代价。线程池不仅能够保证内核的充分利用,还能防止过分调度。

1.2 优点

1.降低资源消耗: 通过重复利用已创建的线程降低线程创建和销毁造成的销耗。

2.提高响应速度: 当任务到达时,任务可以不需要等待线程创建就能立即执行。

3.提高线程的可管理性: 线程是稀缺资源,如果无限制的创建,不仅会销耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控。

1.3 线程池架构

Java 中的线程池是通过 Executor 框架实现的,该框架中用到了 Executor,Executors,ExecutorService,ThreadPoolExecutor 这几个类。

通过查看线程池创建对象的类源代码,newCachedThreadPool、newFixedThreadPool、newScheduledThreadPool、newSingleThreadExecutor 都有new ThreadPoolExecutor

 二   常见线程池实现方式

2.1 常见线程池

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

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

2.2 newFixedThreadPool

1.思路:创建一个定长线程池,10个任务,每个任务自己循环10次输出。分配给3个线程。

定长线程池的大小最好根据系统资源进行设置。如Runtime.getRuntime().availableProcessors()

匿名调用方式

 2.常规调用代码

public class AppleResources implements Runnable 
    public int task=0;

    public AppleResources(int task) 
        this.task = task;
    

    @Override
    public void run() 
        try 
            Thread.sleep(20);
         catch (InterruptedException e) 
            // TODO Auto-generated catch block
            e.printStackTrace();
        
        for(int j=0;j<10;j++)
            System.out.println(Thread.currentThread().getName()+"  正在进行第"+task+"个任务,第"+j+"次循环");
        
    

2.调用

public class FixdThreadPool 
    public static void main(String[] args) 
        //创建一个初始线程为3个的线程池
        ExecutorService pool= Executors.newFixedThreadPool(3);
        for(int i=0;i<10;i++)//10个任务
            final int task=i;
            pool.execute(new AppleResources(i));//每个任务循环10次
        
        System.out.println("all of ten tasks have committed");
        //关闭线程池
        pool.shutdown();
    

3、结果

2.3 newCachedThreadPool

逻辑:创建一个可缓存的线程池,10个任务,每个任务自己循环10次输出。根据情况自动分配线程,创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。

1.代码:

public class AppleResources implements Runnable 
    public int task=0;

    public AppleResources(int task) 
        this.task = task;
    

    @Override
    public void run() 
        try 
            Thread.sleep(20);
         catch (InterruptedException e) 
            // TODO Auto-generated catch block
            e.printStackTrace();
        
        for(int j=0;j<10;j++)
            System.out.println(Thread.currentThread().getName()+"  正在进行第"+task+"个任务,第"+j+"次循环");
        
    

2.调用

public class CachedThreadPool 
    public static void main(String[] args) 
        //创建一个初始线程为3个的线程池
        ExecutorService pool= Executors.newCachedThreadPool();
        for(int i=0;i<10;i++)//10个任务
            final int task=i;
            pool.execute(new AppleResources(i));//每个任务循环10次
        
        System.out.println("all of ten tasks have committed");
        //关闭线程池
        pool.shutdown();
    

3.调取结果部分截图:

 2.4  newScheduledThreadPool

1.思路:10个任务,每个任务自己循环10次输出。分配给5个线程,创建一个定长线程池,支持定时及周期性任务执行

2.代码

public class AppleResources implements Runnable 
    public int task=0;

    public AppleResources(int task) 
        this.task = task;
    

    @Override
    public void run() 
        try 
            Thread.sleep(20);
         catch (InterruptedException e) 
            // TODO Auto-generated catch block
            e.printStackTrace();
        
        for(int j=0;j<10;j++)
            System.out.println(Thread.currentThread().getName()+"  正在进行第"+task+"个任务,第"+j+"次循环");
        
    

 3.调用

package com.ljf.thread.pool;

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

/**
 * @ClassName: ScheduleThreadPool
 * @Description: TODO
 * @Author: liujianfu
 * @Date: 2022/05/08 19:16:01
 * @Version: V1.0
 **/
public class ScheduleThreadPool 
    public static void main(String[] args) 
        //创建一个初始线程为3个的线程池
        ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);
        for(int i=0;i<10;i++)//10个任务
            //scheduledThreadPool.schedule(new AppleResources(i), 3, TimeUnit.SECONDS);//每个任务循环10次
           scheduledThreadPool.scheduleAtFixedRate(new AppleResources(i), 1,5, TimeUnit.SECONDS);
        
        System.out.println("all of ten tasks have committed");
        //关闭线程池
       // scheduledThreadPool.shutdown();
    

4.展示:表示延迟1秒后每3秒执行一次。

  2.5   newSingleThreadExecutor

1.思路:创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行,10个任务,每个任务自己循环10次输出。分配给1个线程。

2代码

package com.ljf.thread.pool;

/**
 * @ClassName: AppleResources
 * @Description: TODO
 * @Author: liujianfu
 * @Date: 2022/05/08 18:09:05
 * @Version: V1.0
 **/
public class AppleResources implements Runnable 
    public int task=0;

    public AppleResources(int task) 
        this.task = task;
    

    @Override
    public void run() 
        try 
            Thread.sleep(20);
         catch (InterruptedException e) 
            // TODO Auto-generated catch block
            e.printStackTrace();
        
        for(int j=0;j<10;j++)
            System.out.println(Thread.currentThread().getName()+"  正在进行第"+task+"个任务,第"+j+"次循环");
        
    

3.调用

public class SingleThreadPool 
    public static void main(String[] args) 
        //创建一个初始线程为3个的线程池
        ExecutorService pool = Executors.newSingleThreadExecutor();
        for(int i=0;i<10;i++)//10个任务
            final int task=i;
            pool.execute(new AppleResources(i));//每个任务循环10次
        
        System.out.println("all of ten tasks have committed");
        //关闭线程池
        pool.shutdown();
    

4.结果: 

 https://www.iteye.com/blog/cuisuqiang-2019372

https://www.iteye.com/blog/huxc-2179106

以上是关于多线程 之 线程池1的主要内容,如果未能解决你的问题,请参考以下文章

Linux:详解多线程(线程池读写锁和CAS无锁编程)

C++并发与多线程 13_线程池浅谈,线程数量总结

线程池

线程池

JUC学习--线程池的学习

一文简单理解Java线程池的问题