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

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的单位等待队列舍弃策略(等待队列满了,最大线程数达到上限了,此时执行这个策略),线程工厂(为线程命名)。


http://www.kler.cn/a/300868.html

相关文章:

  • git操作(Windows中GitHub)
  • 32单片机综合应用案例——智能家居灯光控制系统(二)(内附详细代码讲解!!!)
  • Unity中实现倒计时结束后干一些事情
  • 基于光偏振与光学调制实现白光干涉相移
  • SpringData-Redis缓存之RedisTemplate
  • Gitee图形界面上传(详细步骤)
  • react18基础教程系列--packagejson文件分析
  • “人人都是产品经理”到AI产品经理,赶上风口的人都赚到了钱
  • 「iOS学习」——Masonry学习
  • 区块链学习笔记3--以太坊
  • C#在Winform中截图指定控件中的内容生成图像
  • QGis二次开发 —— 3、程序加载栅格tif与矢量shp文件可进行切换控制,可进行导出/导入工程(附源码)
  • 基于SpringBoot+Vue的小区停车场管理系统
  • 机器学习--支持向量机(SVM)
  • 数据分析-螺旋环状气泡图
  • 聊一下测试计划
  • 安卓开发中LiveData的使用
  • 力扣 55题 跳跃游戏 记录
  • 外贸|基于Java+vue的智慧外贸平台系统(源码+数据库+文档)
  • 国家网络安全宣传周 | 2024年网络安全领域重大政策法规一览
  • 【截图服务 +打包】pkg打包 puppeteer
  • iOS 打包上传保存You do not have required contracts to perform an operation
  • 深入了解CSS混合模式
  • 使用 FHE 实现加密大语言模型
  • 机器人--手眼标定算法
  • Android - NDK:jni传递数组参数,获取数组的返回值