前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java基础-多线程(三)

Java基础-多线程(三)

作者头像
cwl_java
发布2019-11-12 16:39:48
2990
发布2019-11-12 16:39:48
举报
文章被收录于专栏:cwl_Javacwl_Java

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

本文链接:https://blog.csdn.net/weixin_42528266/article/details/103013657

线程通信
  • 应用场景:生产者和消费者问题
  • 假设仓库中只能存放一件产品,生产者将生产出来的产品放入仓库,消费者将仓库中产品取 走消费
  • 如果仓库中没有产品,则生产者将产品放入仓库,否则停止生产并等待,直到仓库中的产品 被消费者取走为止
  • 如果仓库中放有产品,则消费者可以将产品取走消费,否则停止消费并等待,直到仓库中再 次放入产品为止
在这里插入图片描述
在这里插入图片描述
分析
  • 这是一个线程同步问题,生产者和消费者共享同一个资源,并且生产者和消费者之间相互依 赖,互为条件
  • 对于生产者,没有生产产品之前,要通知消费者等待。而生产了产品之后,又需要马上通知 消费者消费
  • 对于消费者,在消费之后,要通知生产者已经消费结束,需要继续生产新产品以供消费
  • 在生产者消费者问题中,仅有synchronized是不够的
    • synchronized可阻止并发更新同一个共享资源,实现了同步
    • synchronized不能用来实现不同线程之间的消息传递(通信)
Java提供了3个方法解决线程之间的通信问题
在这里插入图片描述
在这里插入图片描述
实现思路
  • 定义产品类
  • 定义消费者线程
  • 定义生产者线程
  • 测试运行
更完整的线程生命周期
在这里插入图片描述
在这里插入图片描述
线程组
  • 线程组表示一个线程的集合。
  • 线程组也可以包含其他线程组。线程组构成一棵树。在树中,除了初始线程组外,每个线程 组都有一个父线程组。
  • 顶级线程组名system,线程的默认线程组名称是main
  • 在创建之初,线程被限制到一个组里,而且不能改变到一个不同的组
线程组的作用
  • 统一管理:便于对一组线程进行批量管理线程或线程组对象
  • 安全隔离:允许线程访问有关自己的线程组的信息,但是不允许它访问有关其线程组的父线 程组或其他任何线程组的信息

查看ThreadGroup、Thread构造方法代码,观察默认线程组的情况

什么是线程池
  • 创建和销毁对象是非常耗费时间的
    • 创建对象:需要分配内存等资源
    • 销毁对象:虽然不需要程序员操心,但是垃圾回收器会在后台一直跟踪并销毁
  • 对于经常创建和销毁、使用量特别大的资源,比如并发情况下的线程,对性能影响很大。

思路:创建好多个线程,放入线程池中,使用时直接获取引用,不使用时放回池中。可以避 免频繁创建销毁、实现重复利用 JDK1.5起,提供了内置线程池

线程池的好处
  • 提高响应速度(减少了创建新线程的时间)
  • 降低资源消耗(重复利用线程池中线程,不需要每次都创建)
  • 提高线程的可管理性:避免线程无限制创建、从而销耗系统资源,降低系统稳定性,甚至内 存溢出或者CPU耗尽
线程池的应用场合
  • 需要大量线程,并且完成任务的时间端
  • 对性能要求苛刻
  • 接受突发性的大量请求
JDK的线程池
在这里插入图片描述
在这里插入图片描述
  • Executor:线程池顶级接口,只有一个方法
  • ExecutorService:真正的线程池接口
  • void execute(Runnable command) :执行任务/命令,没有返回值,一般用来执行Runnable
  • <T> Future<T> submit(Callable<T> task):执行任务,有返回值,一般又来执行Callable
  • void shutdown() :关闭连接池
  • AbstractExecutorService:基本实现了ExecutorService的所有方法
  • ThreadPoolExecutor:默认的线程池实现类
  • ScheduledThreadPoolExecutor:实现周期性任务调度的线程池
  • Executors:工具类、线程池的工厂类,用于创建并返回不同类型的线程池
  • Executors.newCachedThreadPool():创建一个可根据需要创建新线程的线程池
  • Executors.newFixedThreadPool(n); 创建一个可重用固定线程数的线程池
  • Executors.newSingleThreadExecutor() :创建一个只有一个线程的线程池
  • Executors.newScheduledThreadPool(n):创建一个线程池,它可安排在给定延迟后运行命令或者定期地执行
线程池参数
  • corePoolSize:核心池的大小
    • 默认情况下,创建了线程池后,线程数为0,当有任务来之后,就会创建一个线程去执行任务。
    • 但是当线程池中线程数量达到corePoolSize,就会把到达的任务放到队列中等待。
  • maximumPoolSize:最大线程数。
    • corePoolSizemaximumPoolSize之间的线程数会自动释放,小于等于corePoolSize的不会释放。当大于了 这个值就会将任务由一个丢弃处理机制来处理。
  • keepAliveTime:线程没有任务时最多保持多长时间后会终止
    • 默认只限于corePoolSizemaximumPoolSize之间的线程
  • TimeUnit:keepAliveTime的时间单位
  • BlockingQueue:存储等待执行的任务的阻塞队列,有多中选择,可以是顺序队列、链式队列等。
ThreadFactory

线程工厂,默认是DefaultThreadFactory,Executors的静态内部类

RejectedExecutionHandler:

拒绝处理任务时的策略。如果线程池的线程已经饱和,并且任务队列也已满,对新的任 务应该采取什么策略。 比如抛出异常、直接舍弃、丢弃队列中最旧任务等,默认是直接抛出异常。 1、CallerRunsPolicy:如果发现线程池还在运行,就直接运行这个线程 2、DiscardOldestPolicy:在线程池的等待队列中,将头取出一个抛弃,然后将当前线程放进去。 3、DiscardPolicy:什么也不做 4、AbortPolicy:java默认,抛出一个异常:

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-11-11 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 线程通信
  • 分析
  • Java提供了3个方法解决线程之间的通信问题
  • 实现思路
  • 更完整的线程生命周期
  • 线程组
  • 线程组的作用
  • 什么是线程池
  • 线程池的好处
  • 线程池的应用场合
  • JDK的线程池
  • 线程池参数
  • ThreadFactory
  • RejectedExecutionHandler:
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档