`

ReadWriteLock用法

阅读更多

       对象的方法中一旦加入synchronized修饰,则任何时刻只能有一个线程访问synchronized修饰的方法。假设有个数据对象拥有写方法与读方法,多线程环境中要想保证数据的安全,需对该对象的读写方法都要加入 synchronized同步块。这样任何线程在写入时,其它线程无法读取与改变数据;如果有线程在读取时,其他线程也无法读取或写入。这种方式在写入操作远大于读操作时,问题不大,而当读取远远大于写入时,会造成性能瓶颈,因为此种情况下读取操作是可以同时进行的,而加锁操作限制了数据的并发读取。  

         ReadWriteLock解决了这个问题,当写操作时,其他线程无法读取或写入数据,而当读操作时,其它线程无法写入数据,但却可以读取数据 。

 

        且看 以下例子

public class ReadWriteLockDemo {
	static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

	public static void main(String[] args) {
		Data data = new Data();
		Worker t1 = new Worker(data,true);
		Worker t2 = new Worker(data,true);
		t1.start();
		t2.start();
	}

	static class Worker extends Thread {
		Data data;
		boolean read;

		public Worker(Data data, boolean read) {
			this.data = data;
			this.read = read;
		}

		public void run() {
			if (read)
				data.get();
			else
				data.set();
		}
	}

	static class Data {
		ReadWriteLock lock = new ReentrantReadWriteLock();
		Lock read = lock.readLock();
		Lock write = lock.writeLock();
		public  void set() {
			write.lock();
			System.out.println(Thread.currentThread().hashCode()
					+ " set:begin " + sdf.format(new Date()));
			try {
				Thread.sleep(5000);
				//
			} catch (Exception e) {

			} finally {
				System.out.println(Thread.currentThread().hashCode() + " set:end "
						+ sdf.format(new Date()));
				write.unlock();
			}
			

		}

		public  int get() {
			read.lock();
			System.out.println(Thread.currentThread().hashCode()
					+ " get :begin " + sdf.format(new Date()));
			try {
				Thread.sleep(5000);
				//
			} catch (Exception e) {

			} finally {
				System.out.println(Thread.currentThread().hashCode() + " get :end "
						+ sdf.format(new Date()));
				read.unlock();
			}
			

			return 1;
		}
	}
}

 

两个线程均是读线程,结果如下

 22474382 get :begin 2011-04-16 18:26:13
4699264 get :begin 2011-04-16 18:26:13
22474382 get :end 2011-04-16 18:26:18
4699264 get :end 2011-04-16 18:26:18

 

两读线程均可同时读取数据,下面看一个是读线程,一个写线程的情况

Data data = new Data();
  Worker t1 = new Worker(data,false);
  Worker t2 = new Worker(data,true);
  
  t2.start();
  Thread.sleep(100);
  t1.start();

 

先启动读取线程,再启动写入线程,看结果 

14718739 get :begin 2011-04-16 18:54:46
14718739 get :end 2011-04-16 18:54:51
14737862 set:begin 2011-04-16 18:54:51
14737862 set:end 2011-04-16 18:54:56

可以看到读取线程工作时,写入线程是不能访问数据的

 

 

 

 

 

分享到:
评论
1 楼 jzhx107 2013-08-05  

相关推荐

    Java多线程编程之读写锁ReadWriteLock用法实例

    主要介绍了Java多线程编程之读写锁ReadWriteLock用法实例,本文直接给出编码实例,需要的朋友可以参考下

    java并发编程专题(七)----(JUC)ReadWriteLock的用法

    主要介绍了java ReadWriteLock的用法,文中讲解非常详细,示例代码帮助大家更好的理解和学习,感兴趣的朋友可以了解下

    locks框架:接口.pdf

    Lock 接口的基本用法: 深入探讨如何使用 Lock 接口来保护共享资源。演示如何通过 lock 和 unlock 方法来实现线程的同步和互斥。 可重入性和重入锁: 解释 Lock 接口的可重入性,讲解同一个线程多次获取锁的机制,...

    NET多线程同步方法详解

    .NET多线程同步方法详解(一):... 除了以上的这些对象之外实现线程同步的还可以使用Thread.Join方法。这种方法比较简单,当你在第一个线程运行时想等待第二个线程执行结果,那么你可以让第二个线程Join进来就可以了。

    关于synchronized、Lock的深入理解

    目录synchronized的缺陷Lock和ReentrantLock常用方法ReadWriteLock和ReentrantReadWriteLockLock和synchronized区别synchronized锁升级公平锁和非公平锁 synchronized的缺陷 众所周知,synchronized锁是JAVA的关键字...

    Java 8无人谈及的八大功能

    Java的核心库不断加入各种复杂的用法来减少访问共享资源时的线程等待时间。其中之一是经典的读写锁(ReadWriteLock),它让你把代码分成两部分:需要互斥的写操作和不需要互斥的读操作。  表面上看起来很不错。...

    indexedmap:索引地图

    可以在多线程上下文中使用 IndexedMap,但它没有任何内置的事务隔离功能,而且由于在整个映射中使用ReadWriteLock以确保始终维护索引,因此效率也不是很高。 预期用例是管理具有用于查询和更新的快速单线程事件...

    javaSE代码实例

    16.4.9 防止错误的使用wait、notify、notifyAll方法 371 16.5 获取当前正在运行的线程 372 16.6 volatile关键字的含义与使用 372 16.7 小结 373 第17章 高级线程开发 374 17.1 线程池的使用 374 17.1.1...

    Java JDK 7学习笔记(国内第一本Java 7,前期版本累计销量5万册)

    11.2.1 lock、readwritelock与condition 349 11.2.2 使用executor 357 11.2.3 并行collection简介 370 11.3 重点复习 373 11.4 课后练习 375 chapter12 通用api 377 12.1 日志 378 12.1.1 日志api简介...

    汪文君高并发编程实战视频资源全集

     高并发编程第三阶段14讲 Unsafe中的方法使用,一半是天使,一半是魔鬼的Unsafe.mp4  高并发编程第三阶段15讲 Unsafe背后的汇编指令,牛逼男人背后的女人_.mp4  高并发编程第三阶段16讲 CountDownLatch经典案例...

    汪文君高并发编程实战视频资源下载.txt

     高并发编程第三阶段14讲 Unsafe中的方法使用,一半是天使,一半是魔鬼的Unsafe.mp4  高并发编程第三阶段15讲 Unsafe背后的汇编指令,牛逼男人背后的女人_.mp4  高并发编程第三阶段16讲 CountDownLatch经典案例...

    optimistic_lock_coupling_rs::lemon:

    论文“乐观锁耦合:一种可扩展且高效的通用同步方法” 在实际项目中,存在许多无锁数据结构,尤其是在存在许多写入冲突时,与数据库相关的数据结构,例如BwTree , Split-Ordered List (也称为无锁哈希表)。 ...

    JAVA核心知识点整理(有效)

    2.2.3. 本地方法区(线程私有) ................................................................................................................ 23 2.2.4. 堆(Heap-线程共享)-运行时数据区 .....................

    java核心知识点整理.pdf

    本地方法区(线程私有) ................................................................................................................ 23 2.2.4. 堆(Heap-线程共享)-运行时数据区 ...........................

Global site tag (gtag.js) - Google Analytics