多线程内容整理3

52 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第2天,点击查看活动详情
其中使用 volatile 可以解决 内存可见性 和 指令重排序问题,但不能解决原子性问题;
使用锁 是解决线程安全的最主要的方法:
1.内置锁 :synchronized
2.可重入锁:Lock(TrrntantLock)

对于同一个业务的多个线程来说,使用synchronized 进行加锁时,要使用同一个对象

synchronized修饰 静态代码块时,用静态类(XXX.class)来修饰锁
修饰普通代码时,可以使用this来修饰
特性:
a.互斥性:只能进入一个线程
b.刷新内存:解决内存不可见
c.可重入:锁中可以再来一个锁

面试题:synchronized是如何实现的?? 从JVM层面来看,synchronized是依靠 监视器Monitor 实现的
从操作系统层面来看,synchronized是基于操作系统的 互斥锁(Mutex)实现的

Lock的实现步骤 1.创建Lock lock = new ReentrantLock([true]);
2.加锁Lock.lock()
3.释放锁lock.unlock();
lock的使用注意事项:
1.unlock一定要放在finally里面,如果没有放到finally中,可能导致锁资源不释放,永久占用的问题
2.lock()一定要放在try的首行;可以避免没有锁却执行释放锁的操作,以及释放锁的错误信息会覆盖业务报错信息,增加调试程序修复程序的复杂度。
synchronized VS Lock(ReentrantLock):面试题
1.Lock更灵活,拥有更多方法,比如tryLock()
2.锁的类型不同,Lock默认是非公平锁,但是可以指定为公平锁 synchronized只能是非公平锁
3.synchronized是JVM层面提供的锁,自动加锁和释放锁,对于开发者无感
Lock手动进行加锁释放锁
4.synchronized可以修饰方法(静态的、普通的)和代码块
Lock只能修饰代码
5.调用Lock 和 synchronized 线程是锁的状态不同
lock方法变成waiting
synchronized会变成blocked