http://blog.csdn.net/ghsau/article/details/7461369
Lock是java.util.concurrent.locks包下的接口,Lock 实现提供了比使用synchronized 方法和语句可获得的更广泛的锁定操作,它能以更优雅的方式处理线程同步问题,我们拿Java线程(二)中的一个例子简单的实现一下和sychronized一样的效果,代码如下:
- 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),我们会有一种需求,在对数据进行读写的时候,为了保证数据的一致性和完整性,需要读和写是互斥的,写和写是互斥的,但是读和读是不需要互斥的,这样读和读不互斥性能更高些,来看一下不考虑互斥情况的代码原型:
- 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() {...}
- 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();// 释放读锁
- }
- }
- }
部分输出结果:
- 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线程(六):线程池
- 下一篇史上最NB程序员的自白
我的同类文章
- •再聊线程池2016-12-09
- •Java线程(十):CAS2014-08-18
- •Java线程(四):线程中断、线程让步、线程睡眠、线程合并2013-12-26
- •Java线程(篇外篇):阻塞队列BlockingQueue2012-10-25
- •Java线程(七):Callable和Future2016-02-05
- •Java线程(十一):Fork/Join-Java并行计算框架2015-07-22
- •Java线程专栏文章汇总2013-12-27
- •Java线程(篇外篇):线程本地变量ThreadLocal2013-11-13
- •Java线程(九):Condition-线程通信更高效的方式2012-04-20
- •Java线程(六):线程池2012-04-09
核心技术类目
-
文章搜索
-
个人资料
- 访问:1695896次
- 积分:11291
- 等级:
- 排名:第1180名
- 原创:95篇
- 转载:7篇
- 译文:3篇
- 评论:906条
-
详细资料
-
姓名:高爽
生日:1989.6
学历:本科
毕业:2012.7
学校:黑龙江科技大学
公司:Qunar
邮箱:[email protected]
私信有BUG,还有内容审核,有问题请发邮件。
-
博客专栏
|
Design Pattern
文章:6篇 阅读:29784 |
|
Java线程
文章:15篇 阅读:628092 |
-
文章分类
-
阅读排行
- Java线程(七):Callable和Future(129083)
- XSS攻击及防御(100097)
- Java线程(二):线程同步synchronized和volatile(93131)
- Java线程(一):线程安全与不安全(76617)
- Java线程(八):锁对象Lock-同步问题更完美的处理方式(71704)
- Java创建WebService服务及客户端实现(64037)
- HashMap深度解析(一)(55800)
- Java线程(九):Condition-线程通信更高效的方式(55738)
- 完全跨域的单点登录(42595)
- Java线程(五):Timer和TimerTask(41754)
-
评论排行
-
最新评论
-
Java
Mail(三):Session、Message详解
lxbfirst: 非常棒,谢谢!
-
完全跨域的单点登录
qqdd130327: @tcnf2015: 在登录web2的时候会重定向到sso系统,这个时候请求就会带上sso认证系...
-
完全跨域的单点登录
qq_23058585: 博主,项目导入后运行出错,是我的环境没配好吗
-
完全跨域的单点登录
qq_23058585: 博主,项目导入后运行出错,是我的环境没配好吗
-
Java线程(七):Callable和Future
pihaigougou: @pk111:用单例搞全局线程池呗
-
Java线程(七):Callable和Future
三千分之一的爱: @pk111:可以,我这里是demo,线程池作为一种池,就应该是全局使用的,但要合理的设置线程池大小...
-
完全跨域的单点登录
julian75: 不错的
-
Java线程(七):Callable和Future
pk111: 楼主你好,请教个问题,高并发下,如果每个请求都新建一个线程池资源很容易耗尽,所以多个Completi...
-
Unrecognized
SSL message, plaintext connection?
mayfla: 路过
-
Java
Mail(三):Session、Message详解
MelloYuki: O(∩_∩)O谢谢 一目了然
-
打赏
synchronized (a.class) {
}
但有一个疑惑:
文章中间例子提到:”我们要实现写入和写入互斥,读取和写入互斥,读取和读取互斥,在set和get方法加入sychronized修饰符“
只是这样操作就能做到读和写互斥吗?
能否解释一下?
已经调了一个对象的synchronize方法,再调用另一synchronize方法不可以,再调用另一非synchronize方法可以,再调用另一synchronize static方法可以
一下子看的太多了 接受不了了
但我得说 你写的很好 已关注