多线程线程池

池化技术即线程池的使用

为什么要使用池化技术?

线程池、连接池、内存池、对象池等

因为线程的创建、销毁是十分消耗资源的,所以线程也需要使用池化技术

什么是池化技术?

池化技术是一种提前准备和保存大量资源的编程技巧,以便在需要时可以重复使用这些预先准备的资源。在请求量大时,它能明显优化应用性能,降低系统频繁建连的资源开销

不懂?

事先准备好资源,谁要用谁拿,用完放回,不用创建与销毁

线程池的相关知识

  • 三大方法
  • 四种策略
  • 七个参数

使用方式

  • 创建线程池
  • 执行runnable接口
  • 线程池关闭

三大方法

//容量为1的线程池
ExecutorService executor1 =  Executors.newSingleThreadExecutor();
//容量为自己指定的线程池
ExecutorService executor = Executors.newFixedThreadPool(10);
//可伸缩的池子
ExecutorService pool = Executors.newCachedThreadPool();

七大参数

  • 三大方法都调用了ThreadPoolExector类
public static ExecutorService newFixedThreadPool(int nThreads) {
    return new ThreadPoolExecutor(nThreads, nThreads,
                                  0L, TimeUnit.MILLISECONDS,
                                  new LinkedBlockingQueue<Runnable>());
}

public static ExecutorService newSingleThreadExecutor() {
    return new FinalizableDelegatedExecutorService
        (new ThreadPoolExecutor(1, 1,
                                0L, TimeUnit.MILLISECONDS,
                                new LinkedBlockingQueue<Runnable>()));
}
public static ExecutorService newSingleThreadExecutor() {
    return new FinalizableDelegatedExecutorService
        (new ThreadPoolExecutor(1, 1,
                                0L, TimeUnit.MILLISECONDS,
                                new LinkedBlockingQueue<Runnable>()));
}



public ThreadPoolExecutor(int corePoolSize,  //核心线程数量
                          int maximumPoolSize, //最大线程数量
                          long keepAliveTime,  //额外工作 =  最大线程 - 核心线程 ,额外工作的如果没有工作,停留的时间
                          TimeUnit unit,       //超时的但闻
                          BlockingQueue<Runnable> workQueue,  //阻塞队列,核心和
                          ThreadFactory threadFactory,        //创建线程的工厂
                          RejectedExecutionHandler handler) {  //拒绝策略
    if (corePoolSize < 0 ||
        maximumPoolSize <= 0 ||
        maximumPoolSize < corePoolSize ||
        keepAliveTime < 0)
        throw new IllegalArgumentException();
    if (workQueue == null || threadFactory == null || handler == null)
        throw new NullPointerException();
    this.corePoolSize = corePoolSize;
    this.maximumPoolSize = maximumPoolSize;
    this.workQueue = workQueue;
    this.keepAliveTime = unit.toNanos(keepAliveTime);
    this.threadFactory = threadFactory;
    this.handler = handler;
}
public class ThreadPool {

    public static void main(String[] args) {
        //创建线程池
        //ExecutorService pool = Executors.newFixedThreadPool(10);
        //ExecutorService singlePool = Executors.newSingleThreadExecutor();
        //ExecutorService cachedThreadPool = Executors.newCachedThreadPool();

        ThreadPoolExecutor executor = new ThreadPoolExecutor(
                2,
                5,
                2,
                TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(3),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy()
        );

        Output output = new Output();

        //执行runnable接口
        for (int i = 1; i <= 100;i++) {
            executor.execute(output);
        }
        executor.shutdown();
    }
}
class Output implements Runnable{

    private volatile int i = 0;


    @Override
    public synchronized void run() {
        System.out.println(Thread.currentThread().getName()+ "====>" + i);
        i++;
    }
}
  • 默认是创建两个线程,核心线程
  • 最大线程数是5个线程
  • 如果是此时线程数量是3,4的时候,就在阻塞队列等着
  • 当阻塞队列满了,调用额外的线程,最多可以调用5个线程
  • 当处理完了,额外调用的线程就会关闭

四种策略

[
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传](https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=C%3A%2FUsers%2Fwang%2FAppData%2FRoaming%2FTypora%2Ftypora-user-images%2Fimage-20240421105132678.png&pos_id=img-zCZJsVYj-1713787150271)

  • AbortPolicy会抛出异常
  • CallerRunsPolicy 哪里来的去哪里,比如上面的方法多余的会让main线程执行
  • DiscardOldestPolicy,替代最先线程的,然后取代他的位置
  • DiscardPolicy丢弃,不做处理,也不异常

抛出一个问题

当多个线程操作同一个资源变量时会出现什么情况

public class ThreadPool {

    public static void main(String[] args) {
        //创建线程池
        ExecutorService pool = Executors.newFixedThreadPool(10);
        Output output = new Output();
        //执行runnable接口
        for (int i = 0; i < 10;i++) {
           pool.execute(output);
        }

        pool.shutdown();
    }
}
class Output implements Runnable{

    private volatile int i = 0;


    @Override
    public synchronized void run() {
        System.out.println(Thread.currentThread().getName()+ "====>" + i);
        i++;
    }
}

先不看答案,能知道输出的结果是什么吗

pool-1-thread-1====>0
pool-1-thread-7====>0
pool-1-thread-9====>0
pool-1-thread-6====>0
pool-1-thread-5====>0
pool-1-thread-3====>0
pool-1-thread-2====>0
pool-1-thread-10====>0
pool-1-thread-8====>0
pool-1-thread-4====>0

因为线程池,创建了十个线程,在初始的时候就创建了,那个时候的 i 的值是1,之后就没有再次调用了i++;并不是以同步线程一个一个的进入的

  • 8
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值