首页 > 其他分享 >线程池的应用-->2

线程池的应用-->2

时间:2024-09-13 08:55:22浏览次数:11  
标签:状态 自定义 -- 任务 线程 应用 new pool

1.自定义线程工程

  • 当需要自定义线程的名字,线程的优先级,精灵线程状态时,需要自定义线程工厂。

  • 如何自定义线程工厂

    1. 自定义工厂类,实现ThreadFactory接口,重写方法newThread()

    2. 在创建线程池对象时,传递上述线程工厂对象

public class Test5 {
    public static void main(String[] args) {
        System.out.println("------------------------");
        ThreadPoolExecutor pool = new ThreadPoolExecutor(
                5,15,
                5, TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(5),
                new MyThreadFactory());

        pool.execute(()->{
            System.out.println("---->"+Thread.currentThread().getName());
        });
    }
}

class MyThreadFactory implements ThreadFactory{

    //int count = 1 ;
    AtomicInteger count = new AtomicInteger(1);
    @Override
    public Thread newThread(Runnable r) {
        Thread t = new Thread(r);
        t.setName("pool-a-thread-"+count.getAndIncrement());
        t.setPriority(8);
        //t.setDaemon(true);
        return t;
    }
}

2.自定义拒绝策略

实现,当前线程池能力不足时,交给另一个线程池来执行。

  1. 自定义拒绝策略类,

  2. 创建线程池对象时,传递自定义拒绝策略对象

3.自动获得线程池

提供了5个方法可以快速获得线程池对象

//适合任务量大,功能简单的任务,需要确保每一次任务都需要快速反应
ExecutorService pool = Executors.newCachedThreadPool();

//线程池中只有一个线程,确保任务顺序执行
//当内部的线程执行任务出错时,会创建一个新线程。
ExecutorService pool = Executors.newSingleThreadExecutor();

//线程池内装载固定数量的线程
ExecutorService pool = Executors.newFixedThreadPool(5);

//可以执行定时任务的线程池
ScheduledExecutorService pool = Executors.newScheduledThreadPool(1);


//工作窃取线程池
//1. 本质是ForkJoinPool
//2. 提供了2个重载构造器,一个传参指定内部线程的数量,第二个不传参默认是逻辑处理器的数量
//3. 工作窃取线程池的机制
//	 所有的线程都是精灵线程
//	 之前的线程池,无论有多少个线程,都只有一个任务队列
//	 当一瞬间有多个线程同时完成任务时,就会同时去队列中获得新任务,此时就会发生阻塞(性能低)
//	 工作窃取线程池内部,每一个线程都配有一个任务队列,当完成任务时,去自己的队列中获取新任务
//	 当自己的队列中的任务完成后,就去其他线程任务队列中"窃取"任务执行
//	 每一个队列都是双端队列,当前线程从a端获取任务,其他线程从b端窃取任务
ExecutorService pool = Executors.newWorkStealingPool();
//延迟指定时间执行
//
pool.schedule(()->{
    System.out.println("-----------------------------");
},5, TimeUnit.SECONDS);


//延迟指定时间,开始执行
//执行后,每隔指定时间,重复执行
//每次执行的时间 会与 间隔时间叠加
 pool.scheduleAtFixedRate(
     ()->{
         for(int i = 1 ;i<=2;i++){
             System.out.println(i);
             try {
                 Thread.sleep(1000);
             } catch (InterruptedException e) {
                 throw new RuntimeException(e);
             }
         }

     },5,2,TimeUnit.SECONDS);



//延迟指定时间,开始执行
//执行后,每隔指定时间,重复执行
//每次执行的时间 不会与 间隔时间叠加
 pool.scheduleWithFixedDelay(
     ()->{
         for(int i = 1 ;i<=2;i++){
             System.out.println(i);
             try {
                 Thread.sleep(1000);
             } catch (InterruptedException e) {
                 throw new RuntimeException(e);
             }
         }

     },5,2,TimeUnit.SECONDS);

4.线程池生命周期

线程的生命周期

创建 -> 就绪 -> 运行 -> 销毁

                            |

                         暂停

线程池生命周期

  • 运行状态 RUNNING

    状态切换:随着线程池对象的创建,就立刻进入运行状态

    状态效果:运行时的线程池,可以接收任务,处理任务,缓存任务

  • 关闭状态 SHUTDOWN

    状态切换:在运行状态时,调用pool.shutdown()方法

    状态效果:线程池不再接收新任务,但会执行完先有的任务及队列中的任务

  • 停止状态 STOP

    状态切换:运行时直接调用pool.shutdownNow()方法

    或处于shutdown状态的线程池完成了所有手头任务,自动进入stop状态

    状态效果:线程池不再接收新任务,清除队列中的任务,中断正在执行的任务

  • 整理状态 TIDYING

    状态切换:没有方法能直接切换到整理状态

    处于stop状态的线程池,完成了所有任务处理工作,自动调用terminated()

    状态效果:逻辑上就是整理,释放资源,类似于finally中做的事

  • 终结状态 TERMINATED

    状态切换:没有方法能直接切换到终结状态

    处于整理状态的线程池,执行完terminated方法,自动进入终结状态

    状态效果:完全关闭线程池

5.并发工具

5.1CountDownLatch类

  • 提供计数器,当所有的线程都执行完毕后,当前线程再执行。

  • 可以代替多线程中的join作用

CountDownLatch latch = new CountDownLatch(5);
latch.countDown() ;//计数器-1
latch.await();//等待计数器为0(阻塞)
public class Test9 {
    static int count = 0 ;
    public static void main(String[] args) throws InterruptedException {
        ThreadPoolExecutor pool = (ThreadPoolExecutor) Executors.newFixedThreadPool(5);
        CountDownLatch latch = new CountDownLatch(5);
        //循环5次,完成5个任务(通过5个线程)
        for(int i=0;i<5;i++){
            pool.execute(()->{
                try {
                    Thread.sleep((int)((Math.random()*4+1)*1000));
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                //每个任务对count累加1000次
                for(int j=0;j<1000;j++){
                    count++ ;
                }
                System.out.println(Thread.currentThread().getName()+"执行完毕");
                latch.countDown();
            });
        }

        latch.await();
        System.out.println(count);

    }
}

5.2Semaphore类

  • 信号量

  • 提供一组信号量,每一个线程都可以申请信号量, 确保指定数量的线程同时执行。

  • 每一个线程执行完毕后,需要释放信号量

Semaphore s = new Semaphore(5);
s.acquire();
s.release();
public static void main(String[] args) {
    Semaphore s = new Semaphore(5);

    ThreadPoolExecutor pool = (ThreadPoolExecutor) Executors.newFixedThreadPool(10);

    for(int i = 1;i<=10;i++) {
        pool.execute(()->{
            try {
                s.acquire();
                System.out.println(Thread.currentThread().getName()+"正在执行");
                Thread.sleep(5000);
                s.release();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        });
    }


}

标签:状态,自定义,--,任务,线程,应用,new,pool
From: https://blog.csdn.net/lzp122390/article/details/142182867

相关文章

  • 使用 Performance API 实现前端资源监控
    1.PerformanceAPI的用处PerformanceAPI是浏览器中内置的一组工具,用于测量和记录页面加载和执行过程中的各类性能指标。它的主要用处包括:监控页面资源加载:跟踪页面中的资源(如CSS、JavaScript、图片)的加载时间。分析页面加载时间:从导航到页面完全渲染的所有时间点。衡量......
  • Linux 运维工程师面试技术问题及答案指南
    Linux运维工程师的角色在IT行业中至关重要,他们负责维护、监控和优化Linux系统的运行。为了帮助求职者更好地准备面试,本文将列出一些常见的面试问题,并提供相应的答案。1.Linux系统管理问题:Linux支持哪些文件系统?如何管理它们?答案:Linux支持多种文件系统,包括但不......
  • metabase 在Ubuntu 20版本上的服务自动重启配置
    创建系统开机后运行脚本在/etc/下创建rc.local文本sudotouch/etc/rc.localsudochmod-R777/etc/rc.local 第一句创建重启后的执行文件,第二句是授权 1.在文件rc.local中编写运行sh文件内容sudovim/etc/rc.local #!/bin/sh-esleep1sudo./metabasefile/re......
  • PbootCMS网站内页打不开提示404的3种常见原因以及解决方法
    PbootCMS网站内页打不开提示404错误通常有几种常见的原因及解决方法:常见原因及解决方法环境配置错误原因:服务器环境配置不当,比如伪静态规则没有正确配置。解决方法:确认伪静态规则文件是否正确复制到了服务器上。通常伪静态规则文件是 .htaccess(Apache)或 nginx.conf(N......
  • 使用 iptables 限制 SSH 连接并允许特定来源 IP 访问的完整指南
    在保护服务器安全时,限制SSH连接是一项重要措施。通过iptables,你可以有效地控制哪些IP地址可以访问你的服务器,从而减少潜在的安全威胁。本文将介绍如何使用iptables禁止所有类型的连接,并允许特定来源IP的连接,提供实战案例和相关的Shell脚本。一、默认拒绝所有连......
  • Linux Selinux详解
    介绍LinuxSELinux是一种安全增强的Linux,它可以让用户和管理员对访问控制有更多的控制。它是一种标签机制,可以对文件和其他对象提供高级别的安全保护,防止未授权的进程或者没有必要访问的授权进程进行滥用。SELinux最初是由美国国家安全局(NSA)开发的,作为一系列使用Linux安全......
  • PbootCMS安全设置解决网站被黑被篡改问题
    在使用PbootCMS时,确保系统的安全性是非常重要的。以下是一些详细的安全防护措施,分为几个方面:权限设置、基础安全设置、主机安全防护、robots.txt防御以及程序定期备份。安全防护一:权限设置为了提高系统的安全性,可以通过设置目录权限来防止未经授权的访问和修改。以下是一些建......
  • 【开题报告】基于Springboot+vue基于Web的游戏道具交易平台系统(程序+源码+论文) 计算
    本系统(程序+源码)带文档lw万字以上文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景随着网络游戏的蓬勃发展,游戏内经济体系日益完善,游戏道具作为虚拟商品已成为玩家间交易的重要组成部分。传统游戏内交易方式受限于平台规则、信任机制......
  • uniapp 手摸手实现左右菜单联动
    对于左右菜单联动的需求是很常见的在小程序里,主要表现为:点击左侧的菜单栏,右侧会切换到对应的内容区域滑动右侧的内容,左侧会自动切换到对应的菜单项主要利用的是scroll-view标签,以及相关的一些API,可参考:uniapp.dcloud.net.cn/api/ui/node…去获取当前的所有节点集合,再配合......
  • pbootcms网站打不开(内页无法正常访问的情况)怎么办?
    当你遇到PbootCMS网站内页无法正常访问的情况时,可以尝试关闭伪静态功能,转而使用兼容模式进行访问。以下是详细的步骤和注意事项:解决方案关闭伪静态,使用兼容模式登录后台管理系统:打开浏览器,输入PbootCMS后台管理地址(通常是 http(s)://yourdomain.com/admin.php)并登录。......