Java 读写锁ReadWriteLock

Java 读写锁ReadWriteLock


读写锁相对于线程互斥的优势在于高效,它不会对两个读线程进行盲目的互斥处理,当读线程数量多于写线程尤其如此,当全是写线程时两者等效。(多用于读多写少时使用)


1.读锁可以允许多个进行读操作的线程同时进入,但不允许写进程进入。
2.写锁只允许一个写进程进入,在这期间任何进程都不能再进入。

注意:每个读写锁都有挂锁和解锁,最好将每一对挂锁和解锁操作都用try、finally来套入中间的代码,这样就会防止因异常的发生而造成死锁得情况。





例子:
import java.util.Random;
import java.util.concurrent.locks.*;

public class ReadWriteLockTest {
	public static void main(String[] args) {
		final TheData myData = new TheData(); // 这是各线程的共享数据
		for (int i = 0; i < 3; i++) { // 开启3个读线程
			new Thread(new Runnable() {
				@Override
				public void run() {
					while (true) {
						myData.get();
					}
				}
			}).start();
		}
		for (int i = 0; i < 3; i++) { // 开启3个写线程
			new Thread(new Runnable() {
				@Override
				public void run() {
					while (true) {
						myData.put(new Random().nextInt(10000));
					}
				}
			}).start();
		}
	}
}

class TheData {
	private Object data = null;
	private ReadWriteLock rwl = new ReentrantReadWriteLock();

	public void get() {
		rwl.readLock().lock(); // 读锁开启,读线程均可进入
		try { // 用try finally来防止因异常而造成的死锁
			System.out.println(Thread.currentThread().getName() + "is ready to read");
			Thread.sleep(new Random().nextInt(100));
			System.out.println(Thread.currentThread().getName() + "have read date" + data);
		} catch (InterruptedException e) {
			e.printStackTrace();
		} finally {
			rwl.readLock().unlock(); // 读锁解锁
		}
	}

	public void put(Object data) {
		rwl.writeLock().lock(); // 写锁开启,这时只有一个写线程进入
		try {
			System.out.println(Thread.currentThread().getName() + "is ready to write");
			Thread.sleep(new Random().nextInt(100));
			this.data = data;
			System.out.println(Thread.currentThread().getName() + "have write date" + data);
		} catch (InterruptedException e) {
			e.printStackTrace();
		} finally {
			rwl.writeLock().unlock(); // 写锁解锁
		}
	}
}



参考(ReentrantReadWriteLock类和ReentrantLock类的区别): http://blog.csdn.net/kai_wei_zhang/article/details/8197061

猜你喜欢

转载自huangyongxing310.iteye.com/blog/2317937