当前位置: 首页 > news >正文

java八股!5(线程创建+并发容器+线程锁)

4种线程锁

synchronized关键字,依赖JVM进行自动加减锁,在资源竞争不激烈,并发度不是非常高的情况下这种方法非常适合,因为可读性高,而且编译器会尽量优化synchronized。
synchronized机制是给共享资源上锁,只有拿到锁的线程才可以对资源进行访问,可以保证同一时刻最多有一个线程执行同一个对象的同步代码。

一般只有考虑到锁的机制是当前性能瓶颈的时候才会切换其他锁。
比如切换成ReentrantLock。可重入锁,这个锁可以被线程多次重复进入进行获取操作。适合在高并发量的情况下使用,需要手动解锁。

atomic信号量:激烈的并发情况下,比reentrantLock性能优一倍左右。缺点是只能同步一个量。一段代码中只能出现一个atomic变量。

并发容器的原理

先介绍常用的list,queue,set,map都是非线程安全的。因此多并发条件下需要程序手动在外部进行同步才能保证可见性。而线程安全的容器,比如hashtable,的加锁机制会导致在高并发的时候,同一时刻只能有一个线程获取table,其他线程进入阻塞状态,影响性能。

因此需要使用并发容器,保证线程安全同时提高性能

什么是并发容器

java.util.concurrent的包中提供了多种并发容器。并发容器降低了锁的粒度,只在容器部分加锁,其他没有操作的部分仍然可以被其他线程访问,提高并发度。
通过CAS算法和部分代码使用synchronized关键字来实现。

CAS算法

CAS是一种无锁算法,类似乐观锁,主要通过三个变量来实现,要更新的变量V,期望值E,新值N。
更新的过程主要是先读取V,进行处理获取新值N,将变量替换前比较V和E是否相同,也就是判断在处理过程中是否有其他线程更新该变量的值,如果有的话那么重新获取新的值进行处理。如果没有更新就直接替换成新值/

并发容器分类

ConcurrentHashMap,前面也提到过,是基于分段锁实现线程安全,将数据结构分成不同的段,对每一段上锁,这样其他线程还能对没上锁的段操作。在JDK8中采用CAS无锁算法实现
CopyOnWriteArrayList, (对应的非并发容器ArrayList)对读操作不加锁,对写操作,先复制一份新的集合,在新集合上面修改,然后把新集合赋值给旧引用,通过volatile保证其可见性,这个过程需要加写锁
CopyOnWriteArraySet:同上list,但set会保证元素不重复,add时先查询是否存在,若不存在再加入进来

线程池

什么是线程池,为什么需要线程池

我们有两种常见的线程处理方法,一种是继承自Thread类,一种是实现runnable接口,Thread类本质上也是实现了一种runnable接口。但是用这两种方法创建的线程在运行结束后都会被销毁。如果线程数量多的话,频繁销毁和创造线程会影响性能而且浪费内存。因此考虑一种机制让线程在运行结束后仍然可以被复用。

java提供了哪几种线程池?使用场景?

fixedThreadPool:提供指定数量的线程。如果有任务进来,而所有线程都处于忙碌状态,那么任务会进入任务队列等待。适用于需要限制当前线程数量的场景。
SingleThreadPool:只能创建一个线程,先进先出的任务队列。适用于保证任务是顺序执行而且不会有多个线程是活动的场景.
CachedThreadPool: 线程数量不固定,如果当前任务产生但线程都处于忙碌状态,那么会新建线程处理当前任务。适用于负载较轻的服务器,或执行很多很短的异步任务的小程序。

创建线程池的方式(好像看到某个面经里有)

1,使用executors创建,但阿里巴巴java开发手册中不允许使用该方法创建线程池,而是通过ThreadPoolExecutor构造函数的方式,这样可以让同学更加明确线程池的运行规则,规避资源耗尽的风险
2,ThreadPoolExecutor,
看了一下小林coding,好像会问这个构造函数的七个参数,这里也写一下
线程池分为核心线程池,等待队列,最大线程数
如果进来的任务,核心线程池没满,就会进入核心线程池分配线程,如果满了,就进入等待队列。如果等待队列满了,就添加新线程,如果线程数超过最大线程数了,就会根据一些策略舍弃掉线程。

七个参数:核心线程数(线程小于等于核心线程数的时候,就算有空闲线程也不会被销毁),最大线程数keepAliveTime(如果线程超过核心线程数,那么线程空闲的时间如果超过规定的keepAliveTime,就会被销毁),time的单位等待队列舍弃策略(等待队列满了,最大线程数达到上限了,此时执行这个策略),线程工厂(为线程命名)。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • [网络原理]关于网络的基本概念 及 协议
  • 郑州建筑智能化乙级资质申请,人员资质要求详解
  • NLP-文本分类文献阅读-前置基础-词汇解释-通俗易懂-9月份-学习总结
  • 如何将 Electron 项目上架 Apple Store
  • JDBC API详解二
  • 基于SSM和VUE的药品管理系统(含源码+sql+视频导入教程+文档)
  • 解锁全球机遇:澳大利亚服务器租用市场的独特魅力
  • 音视频入门基础:WAV专题(9)——FFmpeg源码中计算WAV音频文件每个packet的duration和duration_time的实现
  • 网络原理(3)—— 应用层、传输层(TCP)
  • Redis 是否存在线程安全问题:深入解析与技术分析
  • Robust Image Denoising through Adversarial Frequency Mixup
  • “他人笑我太疯癫,我笑他人看不穿“,关于做知识分享,被Diss,哇哦,真厉害
  • MongoDB 的适用场景
  • SM7015非隔离电磁炉/电饭煲电源芯片12V/18V输出
  • Java设计模式之责任链模式详细讲解和案例示范
  • JavaScript 如何正确处理 Unicode 编码问题!
  • (ckeditor+ckfinder用法)Jquery,js获取ckeditor值
  • 【知识碎片】第三方登录弹窗效果
  • C++类中的特殊成员函数
  • Electron入门介绍
  • Golang-长连接-状态推送
  • JavaScript 是如何工作的:WebRTC 和对等网络的机制!
  • Java基本数据类型之Number
  • JS学习笔记——闭包
  • magento2项目上线注意事项
  • NSTimer学习笔记
  • Promise初体验
  • PyCharm搭建GO开发环境(GO语言学习第1课)
  • 创建一个Struts2项目maven 方式
  • 马上搞懂 GeoJSON
  • 猫头鹰的深夜翻译:JDK9 NotNullOrElse方法
  • 线上 python http server profile 实践
  • ​​​​​​​​​​​​​​汽车网络信息安全分析方法论
  • # 利刃出鞘_Tomcat 核心原理解析(七)
  • #HarmonyOS:基础语法
  • $.proxy和$.extend
  • $forceUpdate()函数
  • (02)Unity使用在线AI大模型(调用Python)
  • (Redis使用系列) Springboot 实现Redis消息的订阅与分布 四
  • (Redis使用系列) SpringBoot 中对应2.0.x版本的Redis配置 一
  • (WSI分类)WSI分类文献小综述 2024
  • (zt)基于Facebook和Flash平台的应用架构解析
  • (安卓)跳转应用市场APP详情页的方式
  • (第一天)包装对象、作用域、创建对象
  • (附源码)基于SpringBoot和Vue的厨到家服务平台的设计与实现 毕业设计 063133
  • (附源码)计算机毕业设计SSM基于健身房管理系统
  • (接口封装)
  • (每日一问)设计模式:设计模式的原则与分类——如何提升代码质量?
  • (七)Flink Watermark
  • (一)u-boot-nand.bin的下载
  • (一)插入排序
  • (转)IOS中获取各种文件的目录路径的方法
  • (转载)Linux 多线程条件变量同步
  • *ST京蓝入股力合节能 着力绿色智慧城市服务
  • ./include/caffe/util/cudnn.hpp: In function ‘const char* cudnnGetErrorString(cudnnStatus_t)’: ./incl