多线程和线程池在实际开发中的应用

1.什么是线程池

线程池是管理线程的池子,他将准备就绪的线程放在池子中(LinkedList),让线程处于就绪的状态(调用start()方法之后就是就绪状态)。

2.为什么使用线程池

一帮我们在项目中不会去平凡的去创建线程关闭线程,这样比较消耗cpu,我们使用线程池可以让线程可以服用,这样就避免的cpu的消耗。

3.几个重要的参数

1、corePoolSize(线程池基本大小):

当向线程池提交一个任务时,若线程池已创建的线程数小于corePoolSize,即便此时存在空闲线程,也会通过创建一个新线程来执行该任务,直到已创建的线程数大于或等于corePoolSize时,(除了利用提交新任务来创建和启动线程(按需构造),也可以通过 prestartCoreThread() 或 prestartAllCoreThreads() 方法来提前启动线程池中的基本线程。)

2、maximumPoolSize(线程池最大大小):

线程池所允许的最大线程个数。当队列满了,且已创建的线程数小于maximumPoolSize,则线程池会创建新的线程来执行任务。另外,对于无界队列,可忽略该参数。

3、keepAliveTime(线程存活保持时间)

当线程池中线程数大于核心线程数时,线程的空闲时间如果超过线程存活时间,那么这个线程就会被销毁,直到线程池中的线程数小于等于核心线程数。

4、workQueue(任务队列):

用于传输和保存等待执行任务的阻塞队列。

5、threadFactory(线程工厂):

用于创建新线程。threadFactory创建的线程也是采用new Thread()方式,threadFactory创建的线程名都具有统一的风格:pool-m-thread-n(m为线程池的编号,n为线程池内的线程编号)。

6、handler(线程饱和策略):

当线程池和队列都满了,再加入线程会执行此策略。

//使用默认的拒绝策略 直接抛出registedException异常阻止程序运行
       // ThreadPoolExecutor executorService = new ThreadPoolExecutor(4,10,5, TimeUnit.SECONDS,new LinkedBlockingQueue(5));
        /**
         * 1.AbortPolicy(默认)    直接抛出RejectedExecutionException异常阻止系统正常运行
         * 2.CallersRunsPolicy    "调用者模式"一种调节机制,该策略既不会抛弃任务,也不会抛出异常,而是将某些任务回退到调用者,从而降低新任务的流量
         * 3.DiscardOldestPolicy  抛弃队列中等待最久的任务,然后把当前任务加入队列中尝试再次提交当前任务
         * 4.DiscardPolicy        直接丢弃任务,不予处理也不抛出异常.如果允许任务丢失,这是最好的一种方案
         */
        //ThreadPoolExecutor executorService = new ThreadPoolExecutor(4,10,5, TimeUnit.SECONDS,new LinkedBlockingQueue(5),new ThreadPoolExecutor.CallerRunsPolicy());

4.线程池原理

一个可以初始化线程的池子,将你设置的线程数在构造函数中生成,通过LinkedList存放,并设置你存放任务队列的大小。
当你有任务进来的时候,核心线程会立即执行,但是如果核心线程不够用了就会放到任务的队列中,任务队列中放满了,就看线程数是否大于最大线程数,没有的画就创建线程,直到最大线程数。所有最大的线程处理数为=最大线程数+队列池的大小。还有一个存活时间,是如果一个线程的空闲时间超过存活时间的画,会和核心线程比较,如果大于核心线程就把他停止掉。

5.实际的应用实例(整合日志,采用多线程记录日志)

在调用addlog,方法的时候通过多线程记录日志

package com.jrm.thread.threadLog;

/**
 * @author Jeremy
 * @title: LogThread
 * @date 2020/3/1214:09
 */
public class LogThread implements Runnable {
    private String msg;
    public LogThread(String msg){
        this.msg = msg;
    }

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName()+"开始记录日志:"+msg);
    }
}
package com.jrm.thread.threadLog;

import com.jrm.model.Member;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

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

/**
 * @author Jeremy
 * @title: MgsController
 * @date 2020/3/1213:58
 */
@RestController
public class MgsController {

    @GetMapping("/addlog")
    public String addlog(Member member){
        System.out.println(Thread.currentThread().getName()+"=整合日志系统");
        ExecutorService executorService = Executors.newFixedThreadPool(3);
        executorService.execute(new LogThread(member.toString()));
        executorService.shutdown();
        return "succcess";
    }

}

6.保证线程安全的执行(推荐使用)

package com.jrm.thread.threadLog;

import java.util.concurrent.locks.Lock;

/**
 * @author Jeremy
 * @title: LogThread
 * @date 2020/3/1214:09
 */
public class LogThread implements Runnable {
    private String msg;
    public LogThread(String msg){
        this.msg = msg;
    }
    private volatile int i = 0;
    public synchronized void run() {
//        try {
//            Thread.sleep(5000);
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }

            if(i%2==0){
                System.out.println(Thread.currentThread().getName()+"开始记录偶数日志:"+msg+"="+i);
            }else {
                System.out.println(Thread.currentThread().getName()+"开始记录奇数日志:"+msg+"="+i);
            }
            i++;


    }
}
package com.jrm.thread.threadLog;

import com.jrm.model.Member;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

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

/**
 * @author Jeremy
 * @title: MgsController
 * @date 2020/3/1213:58
 */
@RestController
public class MgsController {

    @GetMapping("/addlog")
    public String addlog(Member member){
        System.out.println(Thread.currentThread().getName()+"=整合日志系统");
        ExecutorService executorService = Executors.newFixedThreadPool(3);
        LogThread logThread =  new LogThread(member.toString());
        for(int i=0;i<10;i++){
            executorService.execute(logThread);
        }
        executorService.shutdown();
        return "succcess";
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值