• 安卓面试总结(3)——Java 多线程I


    上一篇

    安卓面试总结(2)——Java 集合框架

    本来这篇文章快写好的了,电脑不停的输出字符,生气的砸了一下,直接关机了,内容没保存。不知为何最近这么的暴躁,昨天是静了静,休息了一下,今天上班回来,该写的还是得写啊,人要是没了梦想,活着就是为了等死吗?很喜欢肖申克的救赎里面的一句话,busy living or busy dying,静下心来,努力追求梦想吧!

    前言

    上一篇文章写了 Java 集合框架的内容,我觉得写的还可以吧,虽然都是点到即止,但是希望能够加深读者的印象。在看完源码的前提下,有效的把握重点,由点及面,才能胸有成竹。

    1、线程状态转换

    在这里插入图片描述
    这张图画的很好,注意下里面进入和出去状态的方法,基本线程的大概就有着落了。

    2、多线程的实现

    • Thread

    • Runnable 接口

    • Callable 接口

      FutureTask<Integer> ft = new FutureTask<>(callable);
      Thread thread = new Thread(ft);
      thread.start();
      ft.get();
      
      • 1
      • 2
      • 3
      • 4

    3、线程的 wait、sleep、join 以及 yield

    • wait():
      • 进入到和该对象相关的等待池,师范对象的机锁
      • 可使用 notify、notifyAll 或指定唤醒时间来唤醒
      • wait、notify、notifyAll 必须在 synchronized 块中,否则异常
    • sleep():Thread 静态函数,使线程进入睡眠状态,不能改变锁机制
    • join():等待目标线程完成后再继续执行,target.join(later)
    • yield():让出执行权限,让其他线程优先执行,但是否优先未知

    4、Callable、Future 和 FutureTask

    • Callable:有泛型返回值
    • Future:抽象接口
      • cancel()取消任务
      • isCancel()
      • isDone()
      • V get():获取结果,阻塞等到完成
      • V get(timeout, unit)
    • FutureTask:实现了 RunnableFuture(间接实现了 Runnable、Future)
      • RunnableFuture:接收 Callable 和 Runnable(会包装成 Callable,返回值靠传入)

    5、线程池

    • ① 优点

      • 重用存在线程,减少对象创建、销毁的开销
      • 可有效控制最大并发线程数,提高系统资源的使用率,同时避免过多资源竞争,避免堵塞
      • 提供定时执行、定期执行、单线程、并发数控制等功能
    • ② 线程池都实现了 ExecutorService 接口:submit(有返回值)、execute、shutdown

      • 启动指定数量的线程——ThreadPoolExecutor

        • corePoolSize:线程池说保存的核心线程数
        • maximumPoolSize:线程池穿件的最大线程数(大于核心数存阻塞队列)
        • keepAliveTime:当前线程池线程总数大于核心线程数时,终止多余的空闲线程时间
        • Unit:keepAliveTime 参数时间单位
        • WorkQueue:任务队列
        • threadFactory:线程工厂,让用户定制线程的创建过程,通常不设置
        • Handler:拒绝策略,当线程池和 workQueue 队列都满时的处理策略(默认拒绝并抛出异常)
      • 任务处理过程

        • num < corePoolSize:创建线程
        • corePoolSize < num < maximumPoolSize:存放队列
        • num > maximumPoolSize:处理策略:
          1. 拒绝并抛出异常
          2. 拒绝,再调用线程执行
          3. 删除头任务,重试
          4. 抛弃,无异常
      • Queue 的分类

        1. ArrayBlockingQueue:有界,FIFO排序

        2. LinkedBlockingQueue:无界,FIFO排序

        3. SynchronousQueue:空的,直接将任务提交线程

        4. ProprityBlockingQueue:优先级有界队列

          提供的 Executor(如何由上面知识得出?)

        • CachedThreadPool:一个任务一个线程(maximumPoolSize = 无限 + 空队列)
        • FixedThreadPool:固定大小线程(corePoolSize = maximumPoolSize + 无界队列)
        • SingleThreadExecutor:当线性执行多任务时
    • ③ 定时执行一些任务——ScheduledThreadPoolExecutor

      Executors.newScheduledThreadPool(n)	//线程数
      executorServiece.scheduleAtFixedRate(Runnable, 1, 3, TimeUnit)	//第一次延迟时间,定期时间
      
      • 1
      • 2
    • ④ 线程的使用准则

      • 不要对那些同步等待其他任务结果的任务排序,可能会死锁
      • 理解任务,任务是 CPU 限制的还是 I/O 限制的等,选用正确队列
      • 调整线程池大小,避免线程太大或太小
    • ⑤ shutdown():

      • 关闭所有线程,不再接受,等待所有结束
      • shutdownNow:基于 interrupt 标志实现
      • 记得关闭线程池!!!

    Daemon 守护线程

    • 当所有非守护线程结束时,程序也就终止了,同时会啥事所有守护进程
    • 使用:setDaemon()
    下一篇

    安卓面试总结(4)——Java 多线程II

  • 相关阅读:
    第1次 更多的bash shell命令
    知识储备--基础算法篇-链表
    2022-08-08 第四小组 修身课 学习笔记(every day)
    UGUI性能优化学习笔记(一)网格重建
    ArcGIS直连PostgreSQL(Windows篇)
    xxl-job调度的一致性及路由选择策略
    数据库连接池
    开发者模式:单例模式
    MySQL 通过 Next-Key Locking 技术(行锁+间隙锁)避免幻读问题
    彰显个性│github和gitlab之自定义首页样式
  • 原文地址:https://blog.csdn.net/lfq88/article/details/126915738