Java8基础之ReentrantLock的使用

1.简介

ReentrantLock锁实现了一种可重入锁(reentrat lock),当持有该锁的线程能够重复进入该锁,例如重复调用lock方法,计数器会自增必须通过调用相同次数的unlock进行抵消,其他获取该锁的线程会被挂起,如果抵消的次数不够就会一直挂起
一般都会在finally块中使用unlock,用来确保一定会被解锁

2.api

在这里插入图片描述
构造函数:
在这里插入图片描述
方法:
在这里插入图片描述

3.例子

/**
 * @description 用于测试ReentrantLock锁
 * @author hy
 * @date 2019-10-12
 */

import java.util.concurrent.locks.ReentrantLock;

public class ReentrantLockTest {
	public static void main(String[] args) {
		ReentrantLockTest lockTest = new ReentrantLockTest();
		lockTest.testReentrantLock();
	}

	ReentrantLock lock = new ReentrantLock();

	public void testReentrantLock() {
		new Thread(() -> {
			run();
		}, "A").start();
		new Thread(() -> {
			run();
		}, "B").start();
		new Thread(() -> {
			run();
		}, "C").start();
	}

	// 执行的方法
	public void run() {
		String name = Thread.currentThread().getName();
		for (int i = 0; i < 3; i++) {
			lock.lock();
			System.out.println(name + "线程执行:锁定操作");
			System.out.println(name + "线程执行:业务操作");
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} finally {
				lock.unlock();
				System.out.println(name + "线程执行:解锁操作");
			}
		}
	}
}

当前创建的锁为非公平锁的例子的结果:
在这里插入图片描述
发现当前的执行为抢夺cpu资源的竞争状态的锁!

修改为公平锁 ReentrantLock lock = new ReentrantLock(true);的执行结果:
在这里插入图片描述
发现执行多次都是一样的结果:当前线程按照一定的顺序执行,公平的享有执行的cpu!

4.使用Condition的例子

存钱和取钱的例子

/**
 * @description 测试ReentrantLock的Condition
 * @author hy
 * @date 2019-10-13
 */

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class ReentrantLockConditionTest {
	private ReentrantLock lock = new ReentrantLock();
	private Condition saveable = lock.newCondition();// 定义可以存钱的条件
	private Condition outable = lock.newCondition();// 定义可以取钱的条件

	private volatile int money = 0;

	public int getMoney() {
		try {
			lock.lock();
			return money;
		} finally {
			lock.unlock();
		}

	}

	public void setMoney(int money) {
		try {
			lock.lock();
			this.money = money;
		} finally {
			lock.unlock();
		}
	}

	public static void main(String[] args) {
		ReentrantLockConditionTest conditionTest = new ReentrantLockConditionTest();
		conditionTest.start();
	}

	public void start() {
		new Thread(new Saver()).start();
		new Thread(new Outer()).start();
		new Thread(new Saver()).start();
		new Thread(new Outer()).start();
	}

	//取钱的人
	class Saver implements Runnable {

		@Override
		public void run() {
			while (true) {
				doSaver();// 执行存钱的方法
			}
		}

		// 存钱的方法
		void doSaver() {
			lock.lock();
			if (getMoney() >= 1000) {//对于存钱的来说:当前金额大于等于1000的时候就让存钱的线程停止执行,唤醒取钱的线程
				try {
					saveable.await();
					outable.signal();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			} else {//否者两者线程都唤醒
				saveable.signal();
				outable.signal();
			}
			lock.unlock();
			// 执行存钱的方法
			String name = Thread.currentThread().getName();
			try {
				money += 100;
				System.out.println(name + "-线程执行存钱的操作:+100,当前money=" + money);
				Thread.sleep(200);// 模拟线程延迟
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

	}

	//存钱的人的类
	class Outer implements Runnable {

		@Override
		public void run() {
			while (true) {
				doOuter();// 执行存钱的方法
			}
		}

		// 存钱的方法
		void doOuter() {
			lock.lock();
			if (getMoney() <= 0) {//对于取钱的来说:当前金额小于等于0的时候就让取钱的线程停止执行,唤醒存钱的线程
				try {
					outable.await();
					saveable.signal();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}else{//否者两者线程都唤醒
				outable.signal();
				saveable.signal();
			}
			lock.unlock();
			// 执行存钱的方法
			String name = Thread.currentThread().getName();
			try {
				money -= 100;
				System.out.println(name + "-线程执行存钱的操作:-100,当前money=" + money);
				Thread.sleep(200);// 模拟线程延迟
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
		}

	}
}

结果:
在这里插入图片描述
测试成功!

5.总结

1.在创建ReentrantLock的时候可以通过当前的构造函数设置是否为公平锁和非公平锁

2.通过lock进行锁定通过unlock进行解锁(解锁通常用在finally块)

3.通过ReentrantLock的newCondition方式创建执行的条件,其中使用awiat方法和signal(signalAll)的时候需要先开启锁才能使用(类似于线程中的用法,没有锁的线程是不能执行的)

4.公平锁执行的时候按照一定的顺序执行非公平锁是按照抢夺cpu资源来执行的

以上纯属个人简介,如有问题请联系本人!

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值