前言:
此刻小伙伴们对“java的并发机制是什么”大约比较重视,同学们都需要学习一些“java的并发机制是什么”的相关资讯。那么小编同时在网上汇集了一些有关“java的并发机制是什么””的相关内容,希望同学们能喜欢,姐妹们快快来了解一下吧!1. 锁1) Lock与synchronized的区别Lock是接口,而synchronized是java中的关键字;synchronized不会导致死锁现象发生,而Lock可能造成死锁现象;Lock可以让等待锁的线程响应中断,而synchronized却不行;通过Lock可以知道有没有成功获取锁,而synchronized却无法办到;Lock可以提高多个线程进行读操作的效率;在性能上来说,如果竞争资源不激烈,两者的性能差不多,而当竞争资源非常激烈时(即有大量线程同时竞争),此时Lock的性能要远远优于synchronized。总结:这两者的使用在具体使用时要根据适当情况选择2)公平锁ReentrantLock 设置公平锁true3) 非公平锁ReentrantLock 默认非公平锁,吞吐量比公平锁大4) 可重入锁(递归锁)ReentrantLocksynchronized5) 独占锁(写锁)/独享锁(读锁)/互斥锁 独占锁:指该锁只能被一个线程所有;ReentrantLockSynchronized 共享锁:指该锁可被多个线程所持有;ReentrantReadWriteLock其读锁是共享锁,写锁是独占锁
读锁的共享锁可保证并发读是非常高效的,读写,写读,写写的过程是互斥的。
6)自旋锁
尝试获取锁的线程不会立即阻塞
6)分布式锁(1)具备特性互斥性可重入性锁超时高效高可用支持阻塞和非阻塞支持公平锁和非公平锁(2)实现分布式锁的几种方案数据库实现(悲观与乐观锁)基于Zookeeper实现基于Redis实现自研分布式锁:如谷歌的Chubby分布式锁方案比较:理解难易程序:数据库 < 缓存 < zookeeper实现复杂度:zookeeper <= 缓存 < 数据库性能:缓存 > zookeeper >= 数据库可靠性:zookeeper > 缓存 > 数据库(3)基于Redis分布锁
实现Redisson
7. 死锁死锁的概念:
指两个或两上以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力干涉那它们都无法推进下去,如果系统资源充足,进程的资源请求都能够得到满足,死锁出现的可能性就很低,否则就会因争夺有限的资源而陷入死锁。
产生死锁的原因:系统资源不足进程运行推进的顺序不合适资源分配不当查询java死锁现象的常用命令jps命令定位进程号: jps -l jstack找到死锁查看: jstack 进程号2. 多线程1)线程池线程池的几大参数(7大参数)corePoolSize: 线程池中常驻核心线程数maximumPoolSize:线程池能够容纳同时执行的最大线程数,此值必须大于等于1keepAliveTime: 多余的空闲线程的存活时间(当前线程池数量超过corePoolSize时,当空闲时间达到keepAliveTime值时,多余空闲线程会被销毁直到只剩下corePoolSize个线程为止)unit: keepAliveTime的单位workQueue: 任务队列,被提交但尚未被执行的任务threadFactory: 表示生成线程池中工作线程的线程工厂,用于创建线程一般用默认的即可handler: 拒绝策略,表示当队列满了并且工作线程大于等于线程池的最大线程数(maximumPoolSize)AbortPolicyDiscardPolicyCallerRunsPolicyDiscardOldestPolicy线程池的底层工作原理
线程池的拒绝策略JDK内置的拒绝策略(均实现了RejectedExecutionHandler接口)AbortPolicy(默认): 直接抛出RejectedExecutionException异常阻止系统正常运行;CallerRunsPolicy:“调用者运行”一种调节机制,该策略既不会抛弃任务,也不会抛出异常,而是将某些任务回退到调用者,从而降低新任务的流量;DiscardOldestPolicy:抛弃队列中等待最久的任务,然后把当前任务加入队列中尝试再次提交当前任务;DiscardPolicy:直接丢弃任务,不予任何处理也不抛出异常。如果允许任务丢失,这是最好的一种方案;选择哪一个线程池阿里java手册说明
【强制】线程资源必须通过线程池提供,不允许在应用中自行显式创建线程。
说明:线程池的好处是减少在创建和销毁线程上所消耗的时间以及系统资源的开销,解决资源不足的问 题。如果不使用线程池,有可能造成系统创建大量同类线程而导致消耗完内存或者“过度切换”的问题。
【强制】线程池不允许使用 Executors 去创建,而是通过 ThreadPoolExecutor 的方式,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。
说明:Executors 返回的线程池对象的弊端如下:
FixedThreadPool 和 SingleThreadPool: 允许的请求队列长度为 Integer.MAX_VALUE,可能会堆积大量的请求,从而导致 OOM。CachedThreadPool: 允许的创建线程数量为 Integer.MAX_VALUE,可能会创建大量的线程,从而导致 OOM。合理的配置线程池(maximumPoolSize)CPU密集型:说明:CPU密集一般该任务需要大量的运算,而没有阻塞,CPU一直全速运行,CPU密集任务只有在真正的多核CPU上才可能得到加速(通过多线程)建议:CPU密集型任务配置尽可能少的线程数量参考公式:CPU核数+1个线程的线程池IO密集型:说明:IO密集型任务线程并不是一直在执行任务,则应配置尽可能多的线程IO密集型时,大部分线程都阻塞,故需要多配置线程数参考公式:CPU核*2CPU核数 / (1 - 阻塞系数) 阻塞系数在0.8~0.9之间2) 线程安全(1) 集合a. 线程不安全:ArryList HashSetHashMap
多线程写情况下会抛ConcurrentModificationException异常
b. 线程安全Vectorcollections.synchronizedxxxCopyOnWriteArrayxxxConcurrentMapc. 解决方案:同步向量:new Vector()加锁数组:collections.synchronizedList(new ArrayList())写时复制:new CopyOnWriteArrayList()3. 并发相关概念1)volatile
Java虚拟机提供的轻量级的同步机制
可见性不保证原子性禁止指令重排2) JMM(Java内存模型)
要求的特性
可见性原子性有序性3)CAS (Compare and set )
AtomXX-相关类
缺点:
1. 循环时间长,开销很大(主要是CPU开销)2. 只能保证一个共享变量的原子操作3. 引发ABA问题4)ABA问题原子引用(AtomicReference):时间戳的原子引用(AtomicStampedReference)规避ABA问题 5)ThreadLocalThreadLocal 面试六连问,你能 Hold 住吗?深入剖析ThreadLocal深入分析 ThreadLocal 内存泄漏问题使用 ThreadLocal 变量的时机和方法
标签: #java的并发机制是什么