阿里巴巴面试之利用两个int值实现读写锁
首先我们对读写锁做一个概述:
假设你的程序中涉及到对一些共享资源的读和写操作,且写操作没有读操作那么频繁。在没有写操作的时候,两个线程同时读一个资源没有任何问题,所以应该允许多个线程能在同时读取共享资源。但是如果有一个线程想去写这些共享资源,就不应该再有其它线程对该资源进行读或写,也就是说:读-读能共存,读-写不能共存,写-写不能共存。这就需要一个读/写锁来解决这个问题。
阿里巴巴四面最后的问题就涉及到了读写锁的实现。
问:对JAVA中的读写锁熟悉吗?
我:还可以...
问:简单介绍一下...
我:这是JAVA中的集合类,ReentrantReadWriteLock,分别处理读与写的操作,读读可以共存,读写不能共存,写写不能共存...
问:你自己实现一个读写锁
我:用synchronized,用一个队列...
问:不能那么麻烦,就用两个int值
我:两个int值,那一定是一个标记读次数,一个标记写次数啊,于是想了一会我想出了以下答案:


问:你这个可以是可以,但是如果读操作大量的话,写操作会产生饥饿等待...如何改进?
我想了想,是哦,然后脑子就短路了,挣扎,再挣扎...
我:给写加上优先级
问:不可以,就两个int
我:读次数设置一个阈值,超出主动释放
问:不可以,就两个int
我一脸懵逼...脑补画面
问:提醒你一下,lockwrite那里改一下
面试官发音不标准,我听了个lockread,想了半天,实在不知道怎么改,随便说了一个
问:我让你改lockwrite...
我:额,我看看...
又是漫长的等待...
我:没想出来...
问:把你那个条件拆开,让写占个坑...
我恍然大悟,我去...
然后他大概说了一遍,就草草结束了,郁闷中...
应该改成:

回来之后,大概看了一下,把整个程序写了一下:
package com.darrenchan.lock; /**
* 用两个int变量实现读写锁
* @author Think
*
*/
public class MyReadWriteLock { private int readcount = 0;
private int writecount = 0; public void lockread() throws InterruptedException{
while(writecount > 0){
synchronized(this){
wait();
}
}
readcount++;
//进行读取操作
System.out.println("读操作");
} public void unlockread(){
readcount--;
synchronized(this){
notifyAll();
}
} public void lockwrite() throws InterruptedException{
while(writecount > 0){
synchronized(this){
wait();
}
}
//之所以在这里先++,是先占一个坑,避免读操作太多,从而产生写的饥饿等待
writecount++;
while(readcount > 0){
synchronized(this){
wait();
}
}
//进行写入操作
System.out.println("写操作");
} public void unlockwrite(){
writecount--;
synchronized(this){
notifyAll();
}
} public static void main(String[] args) throws InterruptedException {
MyReadWriteLock readWriteLock = new MyReadWriteLock();
for(int i = 0; i < 2; i++){
Thread2 thread2 = new Thread2(i, readWriteLock);
thread2.start();
} for (int i = 0; i < 10; i++) {
Thread1 thread1 = new Thread1(i, readWriteLock);
thread1.start();
} } } class Thread1 extends Thread{
public int i;
public MyReadWriteLock readWriteLock; public Thread1(int i, MyReadWriteLock readWriteLock) {
this.i = i;
this.readWriteLock = readWriteLock;
} @Override
public void run() {
try {
readWriteLock.lockread();
Thread.sleep(1000);//模拟耗时
System.out.println("第"+i+"个读任务");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
readWriteLock.unlockread();
}
}
} class Thread2 extends Thread{
public int i;
public MyReadWriteLock readWriteLock; public Thread2(int i, MyReadWriteLock readWriteLock) {
this.i = i;
this.readWriteLock = readWriteLock;
} @Override
public void run() {
try {
readWriteLock.lockwrite();
Thread.sleep(1000);
System.out.println("第"+i+"个写任务");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
readWriteLock.unlockwrite();
}
}
}
执行结果:
写操作
第0个写任务
读操作
读操作
读操作
读操作
读操作
读操作
读操作
读操作
读操作
读操作
第9个读任务
第3个读任务
第1个读任务
第8个读任务
第2个读任务
第0个读任务
第7个读任务
第4个读任务
第5个读任务
第6个读任务
写操作
第1个写任务
当然这是简单的,还可以进一步加深,可以参考博客:http://ifeve.com/read-write-locks/#simple
注:以上代码在++和--的时候仍然会产生并发异常,建议用AtomicInteger类型,在硬件上保证++和--操作不会出现并发异常。
阿里巴巴面试之利用两个int值实现读写锁的更多相关文章
- 用两个int值实现读写锁
private int readcount = 0; private int writecount = 0; public void lockread() throws InterruptedExce ...
- 两个int值相乘超过int最大值
System.out.println(100000000*1000 ); //输出结果是:1215752192 先将100000000*1000 的结果转化为二进制: 10111 01001000 0 ...
- 并发系列5-大白话聊聊Java并发面试问题之微服务注册中心的读写锁优化【石杉的架构笔记】
- 问题:两个对象值相同(x.equals(y) == true),但是可能存在hashCode不同吗?
面试官的考察点 这道题仍然是考察JVM层面的基本知识,面试官认为,基本功扎实,才能写出健壮性和稳定性很高的代码. 涉及到的技术知识 (x.equals(y)==true),这段代码,看起来非常简单,但 ...
- Flash图解线程池 | 阿里巴巴面试官希望问的线程池到底是什么?
前言 前几天小强去阿里巴巴面试Java岗,止步于二面. 他和我诉苦自己被虐的多惨多惨,特别是深挖线程和线程池的时候,居然被问到不知道如何作答. 对于他的遭遇,结合他过了一面的那个嘚瑟样,我深表同情(加 ...
- 牛客网Java刷题知识点之Map的两种取值方式keySet和entrySet、HashMap 、Hashtable、TreeMap、LinkedHashMap、ConcurrentHashMap 、WeakHashMap
不多说,直接上干货! 这篇我是从整体出发去写的. 牛客网Java刷题知识点之Java 集合框架的构成.集合框架中的迭代器Iterator.集合框架中的集合接口Collection(List和Set). ...
- two pointers思想 ---- 利用两个i, j两个下标,同时对序列进行扫描,以O(n)复杂度解决问题的一种思想
two pointers思想 ---- 利用两个i, j两个下标,同时对序列进行扫描,以O(n)复杂度解决问题的一种思想, 如果能用这种思想解决问题,那么会大大降低程序的复杂度. 两个利用这个思想的例 ...
- 阿里巴巴--java多线程的两种实现方式,以及二者的区别
阿里巴巴面试的时候,昨天问了我java面试的时候实现java多线程的两种方式,以及二者的区别当时只回答了实现线程的两种方式,但是没有回答上二者的区别: java实现多线程有两种方式: 1.继承Thre ...
- 利用checkbox的到值,并且存到数据库修改的话要显示之前选择的
在前台当然是利用checkbox来得到复选框的语言:{% for language in languages%}<input type="checkbox" name=&qu ...
随机推荐
- dns 监控系统 设计 dns安全威胁的可视化。
基于DNS大数据分析实现宽带共享监控系统.实现对宽带用户进行有效管理. 本系统基于DNS大数据分析实现宽带共享监控系统,包括以下方面. 1)数据采集:数据采集过程是通过探针采集的方式,从各地市的DNS ...
- BZOJ.3495.[PA2010]Riddle(2-SAT 前缀优化建图)
题目链接 每个城市要么建首都要么不建,考虑2-SAT 这样一个国家内城市两两连边是很显然的,但是边数为O(n^2) 每个国家中仅有一个建首都,考虑新建前缀S[i]=1/0这2n个点表示当前国家的[1, ...
- 洛谷.4115.Qtree4/BZOJ.1095.[ZJOI2007]Hide捉迷藏(动态点分治 Heap)
题目链接 洛谷 SPOJ BZOJ1095(简化版) 将每次Solve的重心root连起来,会形成一个深度为logn的树,就叫它点分树吧.. 我们对每个root维护两个东西: 它管辖的子树中所有白点到 ...
- Python3正则表达式(2)
re库常用方法 正则表达式的表示类型: 1.re库采用 raw string 类型(原生字符串类型),不用对转义符再次转义,表示为:r'text' 例如:r'\d{3}-\d{8}' 2.re库采用 ...
- [NOIp2010提高组]关押罪犯
OJ题号:洛谷1525 思路:贪心. 先将所有的人按怨气值从大到小排一下,然后依次尝试将双方分入两个不同的监狱,如果失败(即已分入相同的监狱),则输出这个怨气值. #include<cstdio ...
- ps怎么撤销的三种方法和ps撤销快捷键以及连续撤销多步快捷键
内容提要:文章综合介绍ps撤销快捷键相关的一些操作,包括PS怎么撤销.PS撤销多步.ps连续撤销快捷键.历史记录面板操作等等. 关于ps怎么撤销操作,有多种方法:使用PS撤销快捷键.编辑菜单.文件菜单 ...
- PHP 实现 word/excel/ppt 转换为 PDF
前段时间负责公司内部文件平台的设计,其中有一个需求是要能够在线浏览用户上传的 office 文件. 我的思路是先将 office 转换成 PDF,再通过 pdf.js 插件解析 PDF 文件,使其能在 ...
- how to generate an analog output from a in-built pwm of Atmega 32AVR microcontrloller?
how to generate an analog output from a in-built pwm of Atmega 32AVR microcontrloller? you need a re ...
- ArcGIS Pro 获得工具的个数
import arcgisscripting import string; gp = arcgisscripting.create(9.3); ##多少个工具箱 toolboxes = gp.list ...
- 序列化与反序列化的单例模式实现和readResolve()【转】
如: public class SingleTest implements Serializable{private static final long serialVersionUID = -860 ...