Java 线程池的概念及使用

什么是线程池?
等待池是一个存放等待线程的池子,而线程池也就是一个存放线程的池子,我们可以提前创建好一些线程,当我们有任务的时候去线程池里面拿线程来执行任务,任务执行完成之后又放回线程池

为什么要使用线程池?

  • 使用线程池的原因是因为当我们有很多线程的时候,我们频繁的创建和销毁线程会给我们造成很大的资源开销
  • 线程并发数量过多,抢占系统资源从而导致阻塞
  • 方便我们对线程进行管理

线程池
Executor是线程池的顶级接口,Java通过Executors提供了四种线程池,这四种线程池都是直接或间接配置ThreadPoolExecutor的参数实现的。

  • FixedThreadPool() 固定长度的线程池。可以控制线程的最大并发数
  • CachedThreadPool() 可缓存线程池。线程数无限制,即有空闲线程则复用空闲线程,若无空闲线程则新建线程。
  • SingleThreadExecutor() 只有一个线程的单线程池。主要是为了实现串行
  • ScheduledThreadPool() 定时或周期性执行任务的线程池。

创建线程池的时候,上面三个线程池使用ExecutorService接口,并使用Executors实现类来创建一个线程池
创建定时线程池时,使用ScheduledExecutorService接口,并通过new一个ScheduledThreadPoolExecutor实现类来创建

package experiment;

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

class Person extends Thread{
    @Override
    public void run() {
        System.out.println("买东西...");
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName()+"老板拿来东西...");
    }
}

public class B {
    public static void main(String[] args) {
        ExecutorService executor= Executors.newFixedThreadPool(3);
        Person person=new Person();
        executor.submit(person);
        executor.submit(person);
    }
}

运行结果如下:
在这里插入图片描述
可以看到我们直接启动了两个线程,需要注意的是,但我们的任务数超过我们线程池里面的长度时,系统会拿出所有的线程来执行任务,执行完成之后会再去执行没有执行的任务

使用定时线程池的时候跟其他的线程池不同

package experiment;

import java.util.concurrent.*;

class Person extends Thread{
    @Override
    public void run() {
        System.out.println("买东西...");
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName()+"老板拿来东西...");
    }
}

public class B {
    public static void main(String[] args) {
        ScheduledExecutorService sch=new ScheduledThreadPoolExecutor(3);
        Person person=new Person();
        sch.schedule(person,2, TimeUnit.SECONDS);
        sch.schedule(person,3, TimeUnit.SECONDS);
    }
}


运行结果:
在这里插入图片描述
任务一是在2s之后运行的,任务二是在3s之后运行的,也就是任务一执行之后的1s之后

schedule的参数:参数一是任务,参数二是延迟时间,参数三是时间单位

另外再说一下就是,当我们的任务都执行完毕的时候,我们的程序并没有结束执行,因为我们的线程池还没有关闭,想要关闭可以使用shutdown() 方法

说一个问题就是,如果我们设定了定时任务,但是我们又关闭了线程池,这个时候其实定时任务仍然会执行

package experiment;

import java.util.concurrent.*;

class Person extends Thread{
    @Override
    public void run() {
        System.out.println("买东西...");
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName()+"老板拿来东西...");
    }
}

public class B {
    public static void main(String[] args) {
        ScheduledExecutorService sch=new ScheduledThreadPoolExecutor(3);
        Person person=new Person();
        sch.schedule(person,2, TimeUnit.SECONDS);
        sch.schedule(person,3, TimeUnit.SECONDS);
        sch.shutdown();
        System.out.println("任务结束");
    }
}

解决方法是使用isTerminated
isTerminted() 调用shutdown关闭线程池后,并且所有的任务都执行完毕后返回true

package experiment;

import java.util.concurrent.*;

class Person extends Thread{
    @Override
    public void run() {
        System.out.println("买东西...");
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName()+"老板拿来东西...");
    }
}

public class B {
    public static void main(String[] args) {
        ScheduledExecutorService sch=new ScheduledThreadPoolExecutor(3);
        Person person=new Person();
        sch.schedule(person,2, TimeUnit.SECONDS);
        sch.schedule(person,3, TimeUnit.SECONDS);
        sch.shutdown();
        while(sch.isTerminated()){
            System.out.println("任务结束");
        }
    }
}

有任何不对的地方,欢迎联系改正!!!感谢阅读

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值