ReentrantReadWriteLock特性測試

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);
	}
}

運行結果:java

  當同時運行兩個加讀鎖的線程時,兩個線程不互斥。運行結果爲:架構

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..

測試結果:code

    可見讀寫鎖容許多個線程同時進行讀操做;而當有讀操做時進行寫操做,寫操做將等待讀操做完成後再進行;當有寫操做時,不論讀或是寫,都將被阻塞。這種程序就保證了有寫操做時,不出現髒數據,同時也保證了較好的讀性能,很是適合讀多寫少的架構。
orm

相關文章
相關標籤/搜索