java 锁全面解析(二)
来源:互联网 发布:淘宝怎么给商品打折 编辑:程序博客网 时间:2024/06/17 08:59
接着上篇java 锁全面解析(一)
四、java.util.corrent包
Lock接口及其实现提供了与synchronized关键字类似的同步功能,与synchronized关键字相比,缺少了隐式释放锁的便捷,但是拥有锁获取和释放的可操作性、可中断的获取锁以及超时获取锁等多种同步特性。
1、Lock具备的特性
1)尝试非阻塞地获取锁
2)能被中断的获取锁
3)超时获取锁
常见的使用:
Lock lock = new ReentrantLock();lock.lock();try {} finally {lock.unlock();}
2、Lock底层实现——队列同步器
锁是面向使用者的,它定义了使用者与锁交互的接口,隐藏了实现细节;同步器面向的是锁的实现者,它简化了锁的实现方式,屏蔽了同步状态管理、线程的排队、等待与唤醒等底层操作。
3、Lock基本操作
public interface Lock { void lock(); void lockInterruptibly() throws InterruptedException; boolean tryLock(); boolean tryLock(long time, TimeUnit unit) throws InterruptedException; void unlock(); Condition newCondition();}
1) 重入锁ReentrantLock
指任意线程在获取锁之后能够再次获取该锁而不被阻塞。释放锁时,线程重复n次获取了锁,需要n次释放其他线程才能获取到锁。
2)公平锁
公平性是针对获取锁而言的。如果一个锁是公平的,那么锁的获取顺序准讯FIFO,但通常情况下公平锁的性能会比非公平锁要低。
3)读写锁
允许多个读线程同时 获取锁,但是在写线程获取锁时,所有的读和其他写线程都将被阻塞。
4)锁降级
锁降级是指写锁降级为读锁。
5)condition接口
Condition定义了等待/通知两种类型的方法,当前线程调用这些方法时,需要提前获取到Condition对象关联的锁。Condition对象由Lock对象创建,所以Condition也是依赖Lock对象的。在Condition中,用await()替换wait(),用signal()替换notify(),用signalAll()替换notifyAll()。
4、Lock与synchronized的异同
1)Lock是一个接口,而synchronized是Java中的关键字,synchronized是内置的语言实现;
2)synchronized在发生异常时,会自动释放线程占有的锁,因此不会导致死锁现象发生;而Lock在发生异常时,如果没有主动通过unLock()去释放锁,则很可能造成死锁现象,因此使用Lock时需要在finally块中释放锁;
3)Lock可以让等待锁的线程响应中断,而synchronized却不行,使用synchronized时,等待的线程会一直等待下去,不能够响应中断;
4)通过Lock可以知道有没有成功获取锁,而synchronized却无法办到。
5)Lock可以提高多个线程进行读操作的效率。
class Resource { private final int MAX_SIZE = 100; private LinkedList<Object> list = new LinkedList<Object>(); private Lock lock = new ReentrantLock(); private Condition condition = lock.newCondition(); public void produce(int num) { lock.lock(); try { while (list.size() + num > MAX_SIZE) { System.out.println("Thread " + Thread.currentThread() + " 需要生产已满,等待消费"); condition.await(); } for (int i = 0; i < num; i++) { list.add(new Object()); } System.out.println("【已经生产产品数】:" + num + "【现仓储量为】:" + list.size()); condition.signalAll(); } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); } } public void consume(int num) { lock.lock(); try { while (list.size() < num) { System.out.println("Thread " + Thread.currentThread() + " 消费不足,需要生产"); condition.await(); } for (int i = 0; i < num; i++) { list.remove(); } System.out.println("【已经消费产品数】:" + num + "【现仓储量为】:" + list.size()); condition.signalAll(); } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); } }}
五、ThreadLocal
ThreadLocal存放的值是线程内共享的,线程间互斥的,主要用于线程内共享一些数据,避免通过参数来传递。JVM 为每个运行的线程,绑定了私有的本地实例存取空间,从而为多线程环境常出现的并发访问问题提供了一种隔离机制。
简单来看,ThreadLocal类的实现是依托于一个内部类ThreadLocalMap,存取的时候,先获得当前线程,然后获取到当前线程本地变量Map,最后将当前使用的ThreadLocal和传入的值放到Map中,也就是说ThreadLocalMap中存的值是[ThreadLocal对象, 存放的值]。
- java 锁全面解析(二)
- service全面解析(二)
- 全面解析HTTP(二)
- 【框架基础】:全面解析Java注解(二)
- java 锁全面解析(一)
- 全面解析Java注解(学习笔记)
- 全面解析Java注解
- Java 8全面解析
- Java 8全面解析
- 全面解析Java注解
- 全面解析Java注解
- Java 字符串全面解析
- 全面解析 Java 注解
- Java多线程全面解析
- 全面解析Java注解
- 全面解析Java注解
- Java注解全面解析
- 全面解析Java注解
- 算法总结二
- php数组使用技巧及操作总结
- 利用CImage合并两张图片后保存
- 图像分割
- Unity编辑器-Scene面板里的万向锁现象
- java 锁全面解析(二)
- B
- 12个非常不错的免费HTML后台管理模板
- springboot学习笔记5(JPA 实现分页、排序、返回map集合)
- [DFS]NYOJ 927 The partial sum problem
- hihocoder 1567 偶树的切分(树的深搜)
- JAVA8 新特性--十个
- transform-变形
- vue1.0升级到vue2.0