ReentrantReadWriteLock简单理解和使用

ReentrantReadWriteLock此类不会将读取者优先或写入者优先强加给锁访问的排序。但是,它确实支持可选的公平 策略。

非公平模式(默认)
当非公平地(默认)构造时,未指定进入读写锁的顺序,受到 reentrancy 约束的限制。连续竞争的非公平锁可能无限期地推迟一个或多个 reader 或 writer 线程,但吞吐量通常要高于公平锁。

公平模式
当公平地构造线程时,线程利用一个近似到达顺序的策略来争夺进入。当释放当前保持的锁时,可以为等待时间最长的单个 writer 线程分配写入锁,如果有一组等待时间大于所有正在等待的 writer 线程 的 reader 线程,将为该组分配写入锁。
如果保持写入锁,或者有一个等待的 writer 线程,则试图获得公平读取锁(非重入地)的线程将会阻塞。直到当前最旧的等待 writer 线程已获得并释放了写入锁之后,该线程才会获得读取锁。当然,如果等待 writer 放弃其等待,而保留一个或更多 reader 线程为队列中带有写入锁自由的时间最长的 waiter,则将为那些 reader 分配读取锁。

试图获得公平写入锁的(非重入地)的线程将会阻塞,除非读取锁和写入锁都自由(这意味着没有等待线程)。(注意,非阻塞 ReentrantReadWriteLock.ReadLock.tryLock() 和 ReentrantReadWriteLock.WriteLock.tryLock() 方法不会遵守此公平设置,并将获得锁(如果可能),不考虑等待线程)。

package com.lifei11_27.lock;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * 读锁实现账户的存取
 * 
 * @author Adil
 *
 */
public class ReadLockTest {
	public static void main(String[] args) {
		ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
		ReadLock inMoney = new ReadLock("悟空", 0, 1000, lock);
		ReadLock outMoney = new ReadLock("空空", 2000, 0, lock);

		inMoney.start();
		try {
			Thread.sleep(2000);
			outMoney.start();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

class ReadLock extends Thread {
	static int money = 500;// 预存500元
	private ReentrantReadWriteLock lock;
	private int outMoney;// 取钱
	private int inMoney;// 存钱
	private String userName;

	public ReadLock() {
		// TODO Auto-generated constructor stub
	}

	public ReadLock(String userName, int outMonye, int inMoney, ReentrantReadWriteLock lock) {
		this.userName = userName;
		this.outMoney = outMonye;
		this.inMoney = inMoney;
		this.lock = lock;
	}

	@Override
	public void run() {
		if (inMoney > 0) {
			lock.writeLock().lock();
			System.out.println(userName + "开始存钱,本次存钱金额为:" + inMoney);
			try {
				this.sleep(1000);
				money += inMoney;
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println("存钱成功,余额为:" + money);
			lock.writeLock().unlock();
		}
		if (outMoney > 0) {
			lock.readLock().lock();
			System.out.println(userName + "开始取钱,本次取款金额为:" + outMoney);
			if(outMoney<=money){
				try {
					this.sleep(1000);
					money -= outMoney;
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				System.out.println("取钱成功,余额为:" + money);
			}else{
				System.out.println("对不起 您的账户余额不足");
			}
			lock.readLock().unlock();
		}
	}
}

猜你喜欢

转载自blog.csdn.net/qq_41451415/article/details/84584473