欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

多线程,各种锁,线程安全性问题、线程活跃性问题

程序员文章站 2022-05-17 19:36:55
...

多线程,各种锁,线程安全性问题、线程活跃性问题

线程实现的方式

​ 实现Runnable,继承Thread,匿名内部类,定时器

wait和sleep区别

​ wait锁会被释放,在synchronized中通过notify,notifyAll释放,会释放系统资源

​ sleep锁不会释放,不会释放系统资源,指定时间会自动唤醒

为什么wait和notify、notifyAll要放在synchronized中?

​ 因为他们需要一个同步队列,一个对象锁,一个监视器,只有保证同步才能保证唤醒是同一把锁,只有保证有监视器才能去监视状态,synchronized是一把同步锁和监视器。

活跃性问题

​ 死锁:都有对方的资源,都没有释放,都拿不到想要的资源

​ 饥饿:优先级低的线程就会存在一直获取不到锁的问题,一直轮不到

​ 活锁: 互相礼让

​ 如何解决死锁问题?

​ 互斥条件,占有并等待,非抢占,循环等待

​ 如何解决饥饿问题?

​ 设置优先级,使用synchronized

线程安全性问题

​ 多线程环境下,共享统一资源,非原子性操作会产生安全性问题

​ 解决:使用synchronized同步

​ 偏向锁:每次获取锁和释放锁会浪费资源,一个单线程竞争锁

​ 轻量级锁(自旋锁/无锁):就是一直循环的锁,一个线程只能等待下一个线程结束,才会循环

​ 重量级锁:

​ 锁重入:同一个锁可以被一个线程调用还可以被其他锁调用

​ 公平锁:排队获取锁

​ 不公平锁:争抢锁

读写锁(排他锁和共享锁)

​ 读锁:不互斥/共享锁,效率高

​ 写锁:互斥/排他锁,一次只能一个线程进入

​ 锁降级:将写锁降级为读锁,保证数据一致性

​ 锁升级:将读锁升级为写锁,保证数据一致性,保证数据一致性

 private ReentrantReadWriteLock locks = new ReentrantReadWriteLock();
 private Lock read = locks.readLock();
 private Lock write = locks.writeLock();
Synchronized、DCL(双重检查加锁)

​ 指令重排序:会在不影响最终结果的情况下,执行顺序发生改变

​ 步骤:1.申请一块内存空间 2.在内存中实例化对象 3.引用指向这块空间地址

​ 指令重排序的问题:会出现安全性问题,会出现先执行3,这样对象就不是空了,双重加锁就不起作用

​ 解决办法:加volatile,线程可见性,可以是线程互斥

Volatile

​ 是线程可见性,互斥

AtoMic(原子性操作)

​ 方法:AtomicInteger、Atomic基本类型/数组类型/应用类型

Lock

​ 方便实现公平性

​ 非阻塞的获取锁

​ 能被中断的我获取锁

​ 超时获取锁

AQS(抽象队列同步器)
CAS(比较并交换)
ABA

​ 其他线程修改次数最后值和原值相同,出现线程安全性问题

​ 解决:加版本号

Condition(指定线程释放)

​ 和notifyAll相比它可以指定释放,比较方便

​ 实现类:AQS

​ await(等待),signal(释放)

    private Lock lock = new ReentrantLock();
    private Condition condition = lock.newCondition();

​ 同步队列,等待队列(每new一个就有一个等待队列,和wait只有一个等待队列这是最大的区别)

ThreadLocal(线程局部变量)

​ 线程私有化,解决线程安全性问题

ThreadLocal会产生内存泄漏?

​ java的引用类型:

​ 强引用:GC回收不了的

​ 软引用(softReference):内存不够的时候,会被回收

​ 弱引用(weakReference):只要jvm启动回收,就会被回收

​ 虚引用(phantomReference):管理直接内存,就是一个通知信号,不会get到

​ ThreadLocal 中entry会用到弱引用,通过set会把当前theadlocal作为key,value作为值,会被放在Map中

CyclicBarrier(线程屏障)

​ 允许一组线程全部等待彼此达到共同屏障点的同步辅助。 循环阻塞在涉及固定大小的线程方的程序中很有用,这些线程必须偶尔等待彼此。 屏障被称为循环 ,因为它可以在等待的线程被释放之后重新使用。

​ 简单点就是用来等待线程,等指定的线程到齐了才会运行。

相关标签: 多线程 java