博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java并发集合操作中对锁的应用。
阅读量:6033 次
发布时间:2019-06-20

本文共 2844 字,大约阅读时间需要 9 分钟。

hot3.png

下面以List结合为例子,

先来看以下代码:

public static ArrayList
datas=new ArrayList
();//初始化数据 public static void initData(){ for(int i=0;i<20;i++){ datas.add(""+i); } } //线程1,读取集合的数据 public static Thread thread1=new Thread(){ public void run() { //int size=datas.size(); for(String data:datas){ System.out.println(data); } }; };//线程2,删除集合的数据 private static Thread thread2=new Thread(){ public void run() { int size=datas.size(); for(int i=0;i

这样子运行的话,肯定会出一个异常。下面请看执行的结果
remove
remove
1
remove
remove
remove
remove
remove
remove
Exception in thread "Thread-0" remove
remove
remove
remove
remove
remove
remove
remove
remove
remove
remove
remove
java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:819)
at java.util.ArrayList$Itr.next(ArrayList.java:791)

在现实编程环境中,经常会遇到既需要遍历集合,又需要在另一个线程中删除集合。那么怎么解决呢?

下面就来解决这个问题,我们用到了位于java.util.concurrent.locks包里面的ReentrantReadWriteLock;

简称读写锁,它有两个核心的方法,分别是readLock()和writeLock(),即获取读锁和写锁。获取读锁的前提是写锁没有锁住。获取写锁的前提是读锁没有锁住。也就是保证在读的时候就没有人在写数据或者修改数据。在写数据或者修改数据的时候就没有人在读数据。就好像我们编辑word文档一样,在编辑状态,就不允许移动,复制。根据这个原理,我们接下来改进代码如下:

public static final ReadWriteLock lock = new ReentrantReadWriteLock(false);		public static ArrayList
datas=new ArrayList
(); public static void initData(){ for(int i=0;i<20;i++){ datas.add(""+i); } } public static Thread thread1=new Thread(){ public void run() { lock.readLock().lock(); for(String data:datas){ System.out.println("t1 "+data); } lock.readLock().unlock(); }; }; public static Thread thread3=new Thread(){ public void run() { lock.readLock().lock(); for(String data:datas){ System.out.println("t3 "+data); } lock.readLock().unlock(); }; }; private static Thread thread2=new Thread(){ public void run() { int size=datas.size(); lock.writeLock().lock(); for(int i=0;i

这时候程序执行结果是:

t1  0

t1  1
t1  2
t1  3
t1  4
t1  5
t1  6
t1  7
t1  8
t1  9
t1  10
t1  11
t1  12
t1  13
t1  14
t1  15
t1  16
t1  17
t1  18
t1  19
remove
remove
remove
remove
remove
remove
remove
remove
remove
remove
remove
remove
remove
remove
remove
remove
remove
remove
remove
remove

大家可能疑惑为啥没有t3的打印呢?因为读锁在释放之后,立马就被写锁占用了,写锁的线程把集合清空了,所以当轮到线程3的时候就没有数据了,多试几次,会发现还有一种执行结果就是全部都是remove。没有任何打印,这是因为先执行了线程2的缘故。如果我们按照这样的顺序执行,又会不同:
public static void main(String[] args) {		initData();		thread1.start();		thread3.start();		thread2.start();	}

t3  0
t1  0
t3  1
t1  1
t3  2
t1  2
t3  3
t1  3
t3  4
t1  4
t3  5
t1  5
t3  6
t1  6
t3  7
t1  7
t3  8
t1  8
t3  9
t1  9
t3  10
t1  10
t3  11
t1  11
t3  12
t1  12
t3  13
t1  13
t3  14
t1  14
t3  15
t1  15
t1  16
t1  17
t3  16
t1  18
t1  19
t3  17
t3  18
t3  19
remove
remove
remove
remove
remove
remove
remove
remove
remove
remove
remove
remove
remove
remove
remove
remove
remove
remove
remove
remove
可以看到读锁在不同的线程中是不排斥的。好的,就为大家介绍到这里。

转载于:https://my.oschina.net/zxcholmes/blog/308173

你可能感兴趣的文章
Android热修复升级探索——代码修复冷启动方案
查看>>
学校宿舍的深夜之思考
查看>>
VB.NET 生成DBF文件
查看>>
编译安装nginx 1.9.15
查看>>
我的友情链接
查看>>
新的开始~~~
查看>>
字符串的扩展
查看>>
存储过程中调用webservice
查看>>
神奇语言 python 初识函数
查看>>
Windows安装Composer出现【Composer Security Warning】警告
查看>>
四 指针与数组 五 函数
查看>>
硬盘空间满了
查看>>
dutacm.club Water Problem(矩阵快速幂)
查看>>
深入JVM内核--GC算法和种类
查看>>
iOS的AssetsLibrary框架访问所有相片
查看>>
MySQLdb的安装
查看>>
读书笔记三
查看>>
数论 - 最小乘法逆元
查看>>
企业架构研究总结(22)——TOGAF架构开发方法(ADM)之信息系统架构阶段
查看>>
接口测试(三)--HTTP协议简介
查看>>