• java线程池初步理解


    多线程基础准备

    进程:程序的执行过程,持有资源和线程

    线程:是系统中最小的执行单元,同一个进程可以有多个线程,线程共享进程资源

    线程交互(同步synchronized):包括互斥和协作,互斥通过对象锁实现,协作是多线程竞争同一资源时用wait和notify配合协作

      需要注意的是互斥和协作的前提是同一资源,如果多个线程之间没有对同一个资源进行竞争,那么不叫线程交互,叫多线程就好了。

    线程状态:

    创建状态---创建一个新线程

    就虚状态---start(),等待cpu资源

    运行状态---执行run()方法

    阻塞状态---线程暂停,如sleep,wait等触发

    终止状态---线程销毁

    这些东西都是干货,看起来都很熟悉,但是真正使用的时候会出现各种各样的问题,多写几个ThreadDemo就好了,只是抛砖引玉吧。

    线程池

    作用:限制系统执行线程的数量

    为什么要用线程池:

    1,减少线程创建和销毁的次数,线程创建和销毁的消耗的资源和时间也不可忽略,可能创建和销毁的时间大于任务的执行时间呢!一次创建,多次使用。

    2,根据系统的承受能力,合理控制线程数量,防止无限不合理消耗内存,使服务器死机,一个线程大概要使用1M的内存。

    用到的几个重要的类:

    1,Executor---线程池顶级接口,执行线程的工具接口,并非线程池

    2,ExecutorService---线程池接口

    3,ScheduleExecutorService---和Timer/TimerTask类似,解决任务需要重复执行的问题

    4,ThreadPoolExecutor---ExecutorService的默认实现类

    5,ScheduleThreadPollExecutor---继承ThreadPoolExecutor的ScheduleExecutorService接口的实现类

    常用线程池:

    1,SingleThreadExecutor,单线程的线程池,也就是一个线程串行执行全部任务。

    2,FixedThreadPool,固定大小的线程池,每次提交一个任务先判断核心线程是否已经满了,没满则创建一个新的线程执行任务,满了判断执行队列是否满了,没满把任务放在执行队列,满了判断线程池是否已经满了,没满创建一个新的线程执行任务,满了交给策略处理,如下图:

        

    3,CacheThreadPool,可缓存的线程池,如果线程大小超过了任务需要的线程,就会回收部分空闲线程,当任务量增加时,线程池可以智能的添加新线程来处理任务,对线程的数量不做限制。

    4,ScheduleThreadPool,无限大小的线程池,可以定时及周期性执行任务。

    ThreadPoolExecutor构造方法参数解释

    构造方法

    new ThreadPoolExecutor(CORE_POOL_SIZE,  MAXIMUM_POOL_SIZE, KEEP_ALIVE, UNIT, WORK_QUEUE, THREAD_FACTORY);

    参数解释

    CORE_POOL_SIZE --- 核心线程数

    MAXIMUM_POOL_SIZE --- 最大线程数

    KEEP_ALIVE --- 大于核心线程数的空闲线程等待新任务的时间

    UNIT --- KEEP_ALIVE的时间单位

    WORK_QUEUE --- 执行队列

    THREAD_FACTORY --- 创建新执行任务的工厂

     

    示例线程池代码:

    public class ThreadPoolExample{
        private static final int CORE_POOL_SIZE = 3;
        private static final int MAXIMUM_POOL_SIZE = 10;
        private static final int KEEP_ALIVE = 10;
    
        private static final BlockingQueue<Runnable> WORK_QUEUE = new LinkedBlockingQueue<Runnable>(10);
        private static final ThreadFactory THREAD_FACTORY = new ThreadFactory() {  
            public Thread newThread(Runnable r) {
                return new Thread(r);
            }
        };
        private static final ThreadPoolExecutor THREAD_POOL_EXECUTOR = new ThreadPoolExecutor(CORE_POOL_SIZE,
                MAXIMUM_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS, WORK_QUEUE, THREAD_FACTORY);
        //提交任务
        public void submitTask(Runnable r){
            WORK_QUEUE.add(THREAD_FACTORY.newThread(r));
            //执行排在首位的任务
            THREAD_POOL_EXECUTOR.execute(WORK_QUEUE.poll());
        }
        
        public static void main(String[] args) {
            Runnable r = new Runnable(){
                public void run(){
                    System.out.println("线程开始。。");
                }
            };
            //调用
            new ThreadPoolExample().submitTask(r);
        }
        
    }

    公司不用线程池,就先这样简单的理解一下吧~

  • 相关阅读:
    【硬件】组装一台多核电脑
    【硬件】组装电脑前的准备工作
    【长知识】设计多核电脑装机方案
    【长知识】认识电脑的硬件组成
    程序员必备基础:如何安全传输存储用户密码?
    二本应届生的大学生活、2020年总结(已上岸百度)
    白日梦的Elasticsearch系列笔记(一)基础篇-- 快手上手ES
    全网最牛X的!!! MySQL两阶段提交串讲
    删库后!除了跑路还能干什么?
    数据库面试简答、30道高频面试题
  • 原文地址:https://www.cnblogs.com/dfdi33/p/5280455.html
Copyright © 2020-2023  润新知