文档章节

ReentrantReadWriteLock特性测试

zhengweihao
 zhengweihao
发布于 2015/12/21 13:34
字数 684
阅读 40
收藏 3
package com.zhengweihao.test.concurrent.readwritelock;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;

import org.junit.Test;

public class ReadWriteLockTest {

	private int runOver = 0;

	private static final ExecutorService pool = Executors
			.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
	private static final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
	private static final ReadLock readLock = rwl.readLock();
	private static final WriteLock writeLock = rwl.writeLock();

	/**
	 * 测试读锁不互斥
	 */
	@Test
	public void testReadReadLock() {
		runOver = 2;
		final int sleepTime = 1000;
		pool.execute(new Runnable() {
			public void run() {
				readLock.lock();
				System.out.println("read1 locked " + nowString() + "..");
				sleep(sleepTime);
				System.out.println("read1 unlocked " + nowString() + "..");
				runOver--;
				readLock.unlock();
			}
		});

		pool.execute(new Runnable() {
			public void run() {
				readLock.lock();
				System.out.println("read2 locked " + nowString() + "..");
				sleep(sleepTime);
				System.out.println("read2 unlocked " + nowString() + "..");
				runOver--;
				readLock.unlock();
			}
		});

		while (runOver > 0) {
			sleep(sleepTime);
		}
	}

	/**
	 * 测试读锁阻塞写锁
	 */
	@Test
	public void testReadWriteLock() {
		runOver = 2;
		final int sleepTime = 1000;
		pool.execute(new Runnable() {
			public void run() {
				readLock.lock();
				System.out.println("read locked " + nowString() + "..");
				sleep(sleepTime);
				System.out.println("read unlocked " + nowString() + "..");
				runOver--;
				readLock.unlock();
			}
		});

		pool.execute(new Runnable() {
			public void run() {
				writeLock.lock();
				System.out.println("write locked " + nowString() + "..");
				sleep(sleepTime);
				System.out.println("write unlocked " + nowString() + "..");
				runOver--;
				writeLock.unlock();
			}
		});

		while (runOver > 0) {
			sleep(sleepTime);
		}
	}

	/**
	 * 测试写锁阻塞读锁
	 */
	@Test
	public void testWriteReadLock() {
		runOver = 2;
		final int sleepTime = 1000;

		pool.execute(new Runnable() {
			public void run() {
				writeLock.lock();
				System.out.println("write locked " + nowString() + "..");
				sleep(sleepTime);
				System.out.println("write unlocked " + nowString() + "..");
				runOver--;
				writeLock.unlock();
			}
		});

		pool.execute(new Runnable() {
			public void run() {
				readLock.lock();
				System.out.println("read locked " + nowString() + "..");
				sleep(sleepTime);
				System.out.println("read unlocked " + nowString() + "..");
				runOver--;
				readLock.unlock();
			}
		});

		while (runOver > 0) {
			sleep(sleepTime);
		}
	}

	/**
	 * 测试写锁互斥
	 */
	@Test
	public void testWriteWriteLock() {
		runOver = 2;
		final int sleepTime = 1000;

		pool.execute(new Runnable() {
			public void run() {
				writeLock.lock();
				System.out.println("write1 locked " + nowString() + "..");
				sleep(sleepTime);
				System.out.println("write1 unlocked " + nowString() + "..");
				runOver--;
				writeLock.unlock();
			}
		});

		pool.execute(new Runnable() {
			public void run() {
				writeLock.lock();
				System.out.println("write2 locked " + nowString() + "..");
				sleep(sleepTime);
				System.out.println("write2 unlocked " + nowString() + "..");
				runOver--;
				writeLock.unlock();
			}
		});

		while (runOver > 0) {
			sleep(sleepTime);
		}
	}

	private void sleep(int millis) {
		try {
			Thread.sleep(millis);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	private String nowString() {
		Date date = new Date();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
		return sdf.format(date);
	}
}

运行结果:

  当同时运行两个加读锁的线程时,两个线程不互斥。运行结果为:

read2 locked 2016-01-03 12:09:13..
read1 locked 2016-01-03 12:09:13..
read2 unlocked 2016-01-03 12:09:14..
read1 unlocked 2016-01-03 12:09:14..

  当先运行加读锁线程,再运行加写锁线程时,读锁将阻塞写锁。运行结果为:

read locked 2016-01-03 12:12:43..
read unlocked 2016-01-03 12:12:44..
write locked 2016-01-03 12:12:44..
write unlocked 2016-01-03 12:12:45..

  当先运行加写锁线程,再运行加读锁的线程时,读锁等待写锁解锁。运行结果为:

write locked 2016-01-03 12:14:27..
write unlocked 2016-01-03 12:14:29..
read locked 2016-01-03 12:14:29..
read unlocked 2016-01-03 12:14:30..

  当两个加写锁的线程先后运行,后者将等待前者解锁。运行结果为:

write1 locked 2016-01-03 12:16:05..
write1 unlocked 2016-01-03 12:16:06..
write2 locked 2016-01-03 12:16:06..
write2 unlocked 2016-01-03 12:16:07..

测试结果:

    可见读写锁允许多个线程同时进行读操作;而当有读操作时进行写操作,写操作将等待读操作完成后再进行;当有写操作时,不论读或是写,都将被阻塞。这种程序就保证了有写操作时,不出现脏数据,同时也保证了较好的读性能,非常适合读多写少的架构。

© 著作权归作者所有

共有 人打赏支持
zhengweihao

zhengweihao

粉丝 1
博文 14
码字总数 6336
作品 0
杭州
java锁:synchronized、ReadWriteLock、ReentrantReadWriteLock*

一、先读这篇文章,了解synchronized:Java线程同步:synchronized锁住的是代码还是对象 synchronizied,默认是synchronized(this),括号里的内容可以看成是锁。 把锁当成对象看待,在类C中加...

cjun1990
2016/12/28
6
0
concurrent包 线程池、资源封锁和队列、ReentrantReadWriteLock介绍

jdk1.5后,提供了java.util.concurrent包,它可以实现线程池,你把线程当成普通对象就可以了,它来负责调度和执行 包括两类线程池 固定线程池 可变线程池 延迟线程池 固定线程池 public sta...

JavaGG
2010/03/24
0
0
关于concurrent包 线程池、资源封锁和队列、ReentrantReadWriteLock介绍

jdk1.5后,提供了java.util.concurrent包,它可以实现线程池,你把线程当成普通对象就可以了,它来负责调度和执行 包括两类线程池 固定线程池 可变线程池 延迟线程池 固定线程池 public sta...

JavaGG
2009/06/11
1K
1
ReentrantReadWriteLock读写锁的使用

Lock比传统线程模型中的synchronized方式更加面向对象,与生活中的锁类似,锁本身也应该是一个对象。两个线程执行的代码片段要实现同步互斥的效果,它们必须用同一个Lock对象。   读写锁:...

IT5
05/13
0
0
Java并发编程序列之JUC中的ReentrantLock-ReentrantReadWriteLock

Java并发编程序列之JUC中的ReentrantLock-ReentrantReadWriteLock Hello,大家好,之前两篇关于JUC中AQS的介绍算上大致把AQS是什么,自定义Lock怎么实现讲清楚了,这一篇就来说一说JDK中自带...

2017/12/27
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

深夜胡思乱想

魔兽世界 最近魔兽世界出了新版本, 周末两天升到了满级,比之前的版本体验好很多,做任务不用抢怪了,不用组队打怪也是共享拾取的。技能简化了很多,哪个亮按哪个。 运维 服务器 产品 之间的...

Firxiao
10分钟前
0
0
MySQL 8 在 Windows 下安装及使用

MySQL 8 带来了全新的体验,比如支持 NoSQL、JSON 等,拥有比 MySQL 5.7 两倍以上的性能提升。本文讲解如何在 Windows 下安装 MySQL 8,以及基本的 MySQL 用法。 下载 下载地址 https://dev....

waylau
44分钟前
0
0
微信第三方平台 access_token is invalid or not latest

微信第三方开发平台code换session_key说的特别容易,但是我一使用就带来无穷无尽的烦恼,搞了一整天也无济于事. 现在记录一下解决问题的过程,方便后来人参考. 我遇到的这个问题搜索了整个网络也...

自由的开源
今天
0
0
openJDK之sun.misc.Unsafe类CAS底层实现

注:这篇文章参考了https://www.cnblogs.com/snowater/p/8303698.html 1.sun.misc.Unsafe中CAS方法 在sun.misc.Unsafe中CAS方法如下: compareAndSwapObject(java.lang.Object arg0, long a......

汉斯-冯-拉特
今天
2
0
设计模式之五 责任链模式(Chain of Responsibility)

一. 场景 相信我们都有过这样的经历; 我们去职能部门办理一个事情,先去了A部门,到了地方被告知这件事情由B部门处理; 当我们到了B部门的时候,又被告知这件事情已经移交给了C部门处理; ...

JackieRiver
今天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部