文档章节

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
Java并发编程-读写锁(ReentrantReadWriteLock)

章节目录 ReentrantReadWriteLock 特性 读写锁接口示例 读写锁的实现分析 1. ReentrantReadWriteLock 特性 1.1 读写锁定义 1.2 读写锁使用场景 1.3 读写锁的优点 2.读写锁接口示例 如下为使用...

markfork
05/27
0
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

没有更多内容

加载失败,请刷新页面

加载更多

打包QML程序

1、windeployqt执行路径(D:\Qt\5.12.0\msvc2017_64\bin)加入到PATH中 2、使用Qt自带的命令行交互 Command 终端(Qt 5.12.0 64-bit for Desktop (MSVC 2017))切换到 Release 编译成功的exe...

渣渣曦
29分钟前
0
0
优秀互联网高级测试工程师应该具备的能力

概述 在之前写的互联网高级测试工程师至少具备的能力一文中,提到了测试工程师至少具备的能力,但是并没有提到优秀测试工程师应该具备的能力,下文简单的谈一谈。当然这些全部都是我的个人理...

Sam哥哥聊技术
32分钟前
1
0
webpack项目配置

前端工程化 前端工程化是根据业务特点,将前端开发流程规范化,标准化,它包括了开发流程、技术选型、代码规范、构建发布等等,用语提升前端工程师的开发效率和代码质量。 自动化构建工具 1、...

羊皮卷
35分钟前
0
0
Linux命令备忘录: jobs 显示Linux中的任务列表及任务状态命令

jobs命令用于显示Linux中的任务列表及任务状态,包括后台运行的任务。该命令可以显示任务号及其对应的进程号。其中,任务号是以普通用户的角度进行的,而进程号则是从系统管理员的角度来看的...

开元中国2015
今天
3
0
springboot Whitelabel Error Page(Not Found)解决方案

当出现上图图的错误时注意 报错信息 There was an unexpected error (type=Not Found, status=404). Not Found代表未访问到资源 解决方案:比较访问路径和代码的路径有没有写错 正确的访问路...

斩神魂
今天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部