一、科普定义
这篇博文的两个主角“synchronized”和“读写锁”
1)synchronized
这个同步关键字相信大家都用得比较多,在上一篇“多个线程之间共享数据的方式”中也详细列举他的应用,在这就不多说只做几点归纳:
- Java提供这个关键字,为防止资源冲突提供的内置支持。当任务执行到被synchronized保护的代码片段的时候,它检查锁是否可用,然后获取锁,执行代码,释放锁。
- 常用这个关键字可以修饰成员方法和代码块
2)读写锁
我们对数据的操作无非两种:“读”和“写”,试想一个这样的情景,当十个线程同时读取某个数据时,这个操作应不应该加同步。答案是没必要的。只有以下两种情况需要加同步:
- 这十个线程对这个公共数据既有读又有写
- 这十个线程对公共数据进行写操作
- 以上两点归结起来就一点就是有对数据进行改变的操作就需要同步
所以
java5提供了读写锁
这种锁支持多线程读操作不互斥,多线程读写互斥,多线程写写互斥。
读操作不互斥这样有助于性能的提高,这点在java5以前没有
二.用一道面试题来具体比较这两点
题目:“白板编程,实现一个缓存系统”
题目分析:
对这个缓存系统的理解:
间于用户和数据库中间的一个环节,我们知道用户直接访问数据库的时间是远大于直接访问内存,所以有了缓存区后用户访问数据时 这样,用户先访问缓存区当缓存区有用户需要的数据时直接拿走,当缓存区没有这样的数据,访问数据库并把访问所得的数据放在缓存区,这样当下一个需要这个数据的用户就直接访问内存即可得到。
核心代码实现:
首先用synchronized实现
public synchronized Object getData(String key){ Object result = map.get(key); if(result ==null){ result = "new";//用这步代替访问数据库得数据 } return result; }用读写锁实现
public Object getData(String key){ rw.readLock().lock();//在读前先上读锁 Object result = null; try{ result = map.get(key); //这个if比较关键,它避免了多余的几次对数据哭的读取 if(result==null){ //如果内存中没有所要数据 rw.readLock().unlock(); rw.writeLock().lock(); if(result==null){ try{ //我们用这个代替对数据库访问得到数据的步骤 result = "new"; }finally{ rw.writeLock().unlock(); } rw.readLock().lock(); } } }finally{ rw.readLock().unlock(); } return result; }代码分析:
- 用第一种方法处理,整个过程比较粗线条,代码比较简单单执行效率很低。这种方法的中心思想是不管你是什么操作,但凡涉及到公共资源就都给你同步。这么做可以是可以但是并不好。
- 第二种用读写锁处理显然是对前者的一个优化,对第二种方法做如下几点说明:
- 关于unlock操作,我们知道只要是上了锁就必须要解锁,但是有这么一种情况就是当你上完锁后在执行解锁操作前程序出现异常,那这个所可能就一直存在。所以针对这个问题我们一般将unlock操作放在finally代码块中,就可以保证上了的锁一定会被解。
- 上面的两次if判断,第一个if相信大家很好理解。但为什么要用第二个if呢?再假设一个场景,现在有十个线程来读这个数据,而这个数据又不存在与缓存区,那么这十个线程中最先到的线程将执行“rw.writeLock().lock();”而另外九个线程将被阻塞,当第一个线程读完以后缓存区实际上已经就有了这个数据,但另外九个阻塞在“rw.writeLock().lock();”如果不加这层if他们会继续访问数据库,由此可见加了这层if对整个过程影响很大。这是比较细节的一点,就这一点Java的API文档也考虑到了,它的样例代码如下:
class CachedData { Object data; volatile boolean cacheValid; ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(); void processCachedData() { rwl.readLock().lock(); if (!cacheValid) { // Must release read lock before acquiring write lock rwl.readLock().unlock(); rwl.writeLock().lock(); // Recheck state because another thread might have acquired // write lock and changed state before we did. if (!cacheValid) { data = ... cacheValid = true; } // Downgrade by acquiring read lock before releasing write lock rwl.readLock().lock(); rwl.writeLock().unlock(); // Unlock write, still hold read } use(data); rwl.readLock().unlock(); } }
学习在继续!!!Go!Go!Go!!!
相关推荐
本文将基于标题“Java面试题和练习题”以及描述中提到的内容,深入探讨Java相关的面试题和练习题,旨在帮助求职者或希望提升技能的开发者巩固知识,准备面试。 一、Java基础 1. Java的数据类型:了解Java的八种...
Java作为一门广泛使用的编程语言...而提供的两个PDF文件,"120个Java经典面试题和答案(上)"和"120个Java经典面试题和答案(下)",无疑是复习和准备面试的宝贵资源,可以系统地解答和理解Java面试中可能出现的问题。
- 锁机制:synchronized关键字、Lock接口(ReentrantLock)的使用,读写锁(ReentrantReadWriteLock),以及锁优化。 - 并发工具类:ConcurrentHashMap、BlockingQueue、CountDownLatch、CyclicBarrier、Semaphore...
本资源摘要信息涵盖了Java高级面试题附答案汇总(2021年Java面试题及答案大全),涵盖了多个知识点,包括Java高级面试题、序列化、多线程同步、GC算法、集合类型、JDK自带的监控和性能分析工具等。 1. ...
Java面试题大全,尤其是阿里面试题,是求职者准备Java开发者职位面试的重要参考资料。这份资料集涵盖了广泛的Java编程、设计模式、数据结构、算法、框架、数据库、并发等多个领域的知识点,旨在帮助求职者全面理解...
最后,“mysql经典面试题和互联网大厂mysql面试题.zip”意味着数据库知识同样重要。MySQL是许多互联网公司首选的关系型数据库,面试中会涉及SQL语句优化、索引原理、事务处理、存储引擎的区别(InnoDB与MyISAM)、...
Java的IO体系主要包括字节流(InputStream/OutputStream)和字符流(Reader/Writer),它们用于处理文件读写、网络通信等操作。 #### 18. 集合体系 Java集合框架主要包括List、Set、Map三种集合类型,以及它们的...
5. **锁的种类**:除了Synchronized,Java还有其他类型的锁,如ReentrantLock(可重入锁,功能与Synchronized类似但更灵活)、Semaphore(信号量,控制同时访问特定资源的线程数量)和ReadWriteLock(读写锁,允许多...
### 高并发场景下的关键技术与面试题解析 #### 一、`volatile`关键字及底层原理 **1.1 `volatile`简介** `volatile`是Java虚拟机(JVM)提供的一种轻量级的同步机制,主要用于解决多线程环境中的可见性问题。其核心...
Java面试题超详细解答 Java作为一门广泛应用的编程语言,其面试题目涵盖了众多知识点,从基础语法到高级特性,从理论概念到实际应用。这里我们将深入探讨这些面试题所涉及的Java技术要点。 1. **Java基础** - **...
【吉利汽车Java笔试面试题】是一份专门为应聘者准备的面试资源,主要涵盖了Java编程语言在实际面试中的常见问题和知识点。这份资料旨在帮助求职者更好地理解和掌握Java核心技术,提高他们在吉利汽车公司或其他IT企业...
阿里面试集锦、java面试题大全(附答案)和Java开发岗位面试题汇总等文档,将帮助求职者深入了解并熟练掌握这些内容,从而提高面试成功率。在实际面试过程中,除了理论知识,面试官还会关注候选人的实际编程能力、解决...
### 黑马面试题总结 #### 一、进程与线程状态 **知识点:** - **进程与线程的区别:** - **进程**:是系统进行资源分配和调度的基本单位,每个进程都有独立的代码和数据空间(程序上下文)。 - **线程**:是...
### 并发编程锁面试题解析 #### 一、并发编程与锁基础知识 **1.1 什么是并发编程?** 并发编程是指在一个程序中同时执行多个任务的能力。它旨在提高程序的性能和效率,特别是在多核处理器环境中。通过合理地管理...
### 线程编程面试题详解 #### 60、Java中有几种方法可以实现一个线程?用什么关键字修饰同步方法? stop()和suspend()方法为何不推荐使用? - **实现线程的方法**:Java中实现线程有两种基本方式: - 继承`Thread`...
Java作为一门广泛使用的编程语言,其面试题涵盖了各种层面,从基础语法到高级特性,再到设计模式和系统架构。这份“Java常见面试题.rar”压缩包文件显然为求职者提供了全面的准备材料,旨在帮助他们应对可能出现的...
Java作为一门广泛使用的编程语言,其面试题涵盖了众多领域,包括基础、并发编程、网络、虚拟机、大数据处理以及各种框架。以下是对这些面试题集合的详细解析: 1. **BIO, NIO, AIO, Netty面试题 35道**: - **BIO*...
以下是一些基于“java常见面试题合集”的相关知识点: 1. **基础语法**: - 类与对象:理解类的定义、对象的创建与访问权限。 - 继承与多态:掌握单一继承和接口的多实现,以及方法的重写和重载。 - 封装与抽象...
这篇面试题集锦旨在帮助求职者和开发者深入理解这两个领域的核心概念和技术,以应对各种面试挑战。 首先,JAVA作为一门广泛使用的面向对象编程语言,其面试题通常会涵盖以下几个方面: 1. **JAVA基础**:包括数据...
在本文中,我们将对 2019 金三银四 30 家公司面试题汇总进行深入分析,从 Java 基础到高并发、Spring、数据库、消息队列、分布式系统和 JVM 等技术栈进行讨论。 一、Java 基础 Java 基础知识点包括集合框架的继承...