Java线程(八):锁对象Lock-同步问题更完美的处理方式
程序开发
2023-09-19 09:46:58
http://blog.csdn.net/ghsau/article/details/7461369
Lock是java.util.concurrent.locks包下的接口,Lock 实现提供了比使用synchronized 方法和语句可获得的更广泛的锁定操作,它能以更优雅的方式处理线程同步问题,我们拿Java线程(二)中的一个例子简单的实现一下和sychronized一样的效果,代码如下:
[java] view plain copy print ?- public class LockTest {
- public static void main(String[] args) {
- final Outputter1 output = new Outputter1();
- new Thread() {
- public void run() {
- output.output("zhangsan");
- };
- }.start();
- new Thread() {
- public void run() {
- output.output("lisi");
- };
- }.start();
- }
- }
- class Outputter1 {
- private Lock lock = new ReentrantLock();// 锁对象
- public void output(String name) {
- // TODO 线程输出方法
- lock.lock();// 得到锁
- try {
- for(int i = 0; i < name.length(); i++) {
- System.out.print(name.charAt(i));
- }
- } finally {
- lock.unlock();// 释放锁
- }
- }
- }
如果说这就是Lock,那么它不能成为同步问题更完美的处理方式,下面要介绍的是读写锁(ReadWriteLock),我们会有一种需求,在对数据进行读写的时候,为了保证数据的一致性和完整性,需要读和写是互斥的,写和写是互斥的,但是读和读是不需要互斥的,这样读和读不互斥性能更高些,来看一下不考虑互斥情况的代码原型:
[java] view plain copy print ?- public class ReadWriteLockTest {
- public static void main(String[] args) {
- final Data data = new Data();
- for (int i = 0; i < 3; i++) {
- new Thread(new Runnable() {
- public void run() {
- for (int j = 0; j < 5; j++) {
- data.set(new Random().nextInt(30));
- }
- }
- }).start();
- }
- for (int i = 0; i < 3; i++) {
- new Thread(new Runnable() {
- public void run() {
- for (int j = 0; j < 5; j++) {
- data.get();
- }
- }
- }).start();
- }
- }
- }
- class Data {
- private int data;// 共享数据
- public void set(int data) {
- System.out.println(Thread.currentThread().getName() + "准备写入数据");
- try {
- Thread.sleep(20);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- this.data = data;
- System.out.println(Thread.currentThread().getName() + "写入" + this.data);
- }
- public void get() {
- System.out.println(Thread.currentThread().getName() + "准备读取数据");
- try {
- Thread.sleep(20);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- System.out.println(Thread.currentThread().getName() + "读取" + this.data);
- }
- }
- Thread-1准备写入数据
- Thread-3准备读取数据
- Thread-2准备写入数据
- Thread-0准备写入数据
- Thread-4准备读取数据
- Thread-5准备读取数据
- Thread-2写入12
- Thread-4读取12
- Thread-5读取5
- Thread-1写入12
- public synchronized void set(int data) {...}
- public synchronized void get() {...}
[java] view plain copy print ?
- Thread-0准备写入数据
- Thread-0写入9
- Thread-5准备读取数据
- Thread-5读取9
- Thread-5准备读取数据
- Thread-5读取9
- Thread-5准备读取数据
- Thread-5读取9
- Thread-5准备读取数据
- Thread-5读取9
- class Data {
- private int data;// 共享数据
- private ReadWriteLock rwl = new ReentrantReadWriteLock();
- public void set(int data) {
- rwl.writeLock().lock();// 取到写锁
- try {
- System.out.println(Thread.currentThread().getName() + "准备写入数据");
- try {
- Thread.sleep(20);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- this.data = data;
- System.out.println(Thread.currentThread().getName() + "写入" + this.data);
- } finally {
- rwl.writeLock().unlock();// 释放写锁
- }
- }
- public void get() {
- rwl.readLock().lock();// 取到读锁
- try {
- System.out.println(Thread.currentThread().getName() + "准备读取数据");
- try {
- Thread.sleep(20);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- System.out.println(Thread.currentThread().getName() + "读取" + this.data);
- } finally {
- rwl.readLock().unlock();// 释放读锁
- }
- }
- }
部分输出结果:
[java] view plain copy print ?- Thread-4准备读取数据
- Thread-3准备读取数据
- Thread-5准备读取数据
- Thread-5读取18
- Thread-4读取18
- Thread-3读取18
- Thread-2准备写入数据
- Thread-2写入6
- Thread-2准备写入数据
- Thread-2写入10
- Thread-1准备写入数据
- Thread-1写入22
- Thread-5准备读取数据
从结果可以看出实现了我们的需求,这只是锁的基本用法,锁的机制还需要继续深入学习。
本文来自:高爽|Coder,原文地址:http://blog.csdn.net/ghsau/article/details/7461369,转载请注明。
- 顶
- 25
- 踩
- 2
我的同类文章
更多文章- 猜你在找
- Java面向对象编程(高手养成记)
- JavaSE之多线程实战视频课程
- Java基础核心技术:多线程(day16-day17)
- ArcGIS for javascript 项目实战(环境监测系统)
- ArcGIS for JavaScript
- 8楼 guzhichongshi 2017-01-18 11:48发表 [回复]
- 你好,我想请问个锁的问题,现在有一个类a,实例化出了多个对象A,B,C,D……每个对象都是被多线程操作,单独操作一个对象的时候加锁住对象即可,但如果会同时操作多个对象要如何处理
- Re: 三千分之一的爱 2017-03-13 10:41发表 [回复]
- 回复guzhichongshi:锁住类
synchronized (a.class) {
}
- 7楼 pandajava 2016-05-31 14:15发表 [回复]
- 学习学习学习学习学习
- 6楼 思念叨火车 2016-03-04 14:00发表 [回复]
- 写的很好,受益良多。
但有一个疑惑:
文章中间例子提到:”我们要实现写入和写入互斥,读取和写入互斥,读取和读取互斥,在set和get方法加入sychronized修饰符“
只是这样操作就能做到读和写互斥吗?
能否解释一下?- Re: 张君君 2017-03-11 21:25发表 [回复]
- [reply]liyuchong2537631[/reply
已经调了一个对象的synchronize方法,再调用另一synchronize方法不可以,再调用另一非synchronize方法可以,再调用另一synchronize static方法可以
- Re: 三千分之一的爱 2016-03-05 07:43发表 [回复]
- 回复思念叨火车:synchronized锁的是对象,而不是某个方法。
- 5楼 秦子 2016-01-25 21:28发表 [回复]
- 请问, private int data. 这个属性不加volatile关键字会不会有问题啊
- Re: 三千分之一的爱 2016-01-27 08:48发表 [回复]
- 回复秦子:不会
- 4楼 zsjxq_gg 2015-06-05 10:14发表 [回复]
- 你举的最后一个例子里面,线程写的数据不一定能被读到,怎么保证线程写的数据一定能被另外一个线程读到呢
- Re: 三千分之一的爱 2015-06-06 14:33发表 [回复]
- 回复zsjxq_gg:肯定要先写入才能读到
- 3楼 程序员小董 2015-01-12 21:51发表 [回复]
- 说实话 今天在你的并发专栏里 看的头都大了
一下子看的太多了 接受不了了
但我得说 你写的很好 已关注- Re: 三千分之一的爱 2015-01-16 11:21发表 [回复]
- 回复程序员小董:呵呵,循序渐进
- 2楼 diquren 2013-12-11 16:54发表 [回复]
- get()方法里面,不写rwl.readLock().lock()也可以达到同样并发的效果吧
- Re: 三千分之一的爱 2013-12-12 07:48发表 [回复]
- 回复diquren:读和写也需要互斥。
- Re: diquren 2013-12-13 15:52发表 [回复]
- 回复三千分之一的爱:嗯明白了,有没办法,让方法同步,又是并发(不互斥)。比如:A线程调用了 对象obj的 get()的同步方法,同时B线程也可以调用对象obj的hello()同步方法。
- Re: 三千分之一的爱 2013-12-16 12:24发表 [回复]
- 回复diquren:用本文提到的读写锁就可以实现你说的这个效果啊,传统的synchronized是不行的。
- Re: diquren 2013-12-17 12:18发表 [回复]
- 回复三千分之一的爱:比如你文章最后输出:Thread-4准备读取数据 Thread-3准备读取数据 Thread-5准备读取数据 读与读并不是同步的。一个同步方法用一个单独的Lock对象(两个同步,就要两个Lock),我试了,可以达到效果。
- 1楼 nuonuodaodao 2012-04-14 22:35发表 [回复]
- 顶,并发包还没掌握
- Re: 三千分之一的爱 2012-04-14 22:38发表 [回复]
- 回复nuonuodaodao:呵呵,我也是初步学习。
核心技术类目
全部主题 Hadoop AWS 移动游戏 Java Android iOS Swift 智能硬件 Docker OpenStack VPN Spark ERP IE10 Eclipse CRM JavaScript 数据库 Ubuntu NFC WAP jQuery BI HTML5 Spring Apache .NET API HTML SDK IIS Fedora XML LBS Unity Splashtop UML components Windows Mobile Rails QEMU KDE Cassandra CloudStack FTC coremail OPhone CouchBase 云计算 iOS6 Rackspace Web App SpringSide Maemo Compuware 大数据 aptech Perl Tornado Ruby Hibernate ThinkPHP HBase Pure Solr Angular Cloud Foundry Redis Scala Django Bootstrap- 原创:95篇
- 转载:7篇
- 译文:3篇
- 评论:906条
- Design Pattern
文章:6篇
阅读:29784 Java线程文章:15篇
阅读:628092
标签:
上一篇:
[前端]JavaScript图片切换
下一篇:
相关文章
-
无相关信息