更多技术文章请访问我的个人博客http://www.rain1024.com
同步锁Lock是一种更强大的线程同步机制,通过显式定义同步锁对象来实现线程同步。同步锁提供了比同步代码块,同步方法更广泛的锁定操作,实现更灵活
Lock是控制多个线程对共享资源进行访问的工具,能够对共享资源进行独占访问,每次只能有一个线程对Lock对象加锁,线程访问共享资源之前需要先获得Lock对象,某些锁可能允许对共享资源并发访问。
【示例】使用ReentrantLock锁
class MyClass{
//1.定义锁对象
private final ReentrantLock lock = new ReentrantLock();
//定义需要保证线程安全的方法
public void myMethod(){
//2.加锁
lock.lock();
try {
//需要保证线程安全的代码
}finally {
//3.释放锁
lock.unlock();
}
}
}
- 加锁和释放锁需要放在线程安全的方法中;
- lock.unlock()放在finally语句中,不管发生异常与否,都需要释放锁
下面在银行账户类中增加一个同步锁
BankAccount.java
package com.rain.demo;
import java.util.concurrent.locks.ReentrantLock;
/**
* Created by w-pc on 2017/02/24.
*
* 模拟银行账户
* */
public class BankAccount {
//银行账户
private String bankNo;
//银行余额
private double balance;
//定义锁对象
private final ReentrantLock lock = new ReentrantLock();
//构造方法
public BankAccount(String bankNo,double balance) {
this.bankNo = bankNo;
this.balance = balance;
}
public void setBankNo(String bankNo) {
this.bankNo = bankNo;
}
public void setBalance(double balance) {
this.balance = balance;
}
public double getBalance() {
return balance;
}
public String getBankNo() {
return bankNo;
}
public void access(double money){
//加锁
lock.lock();
try {
if (money < 0 && balance - money < 0) {
System.out.println(Thread.currentThread().getName()+"操作失败");
return;
} else {
balance += money;
System.out.println(Thread.currentThread().getName()+"操作成功,当前余额:" + balance);
//设定休眠一毫秒,使其他线程得以执行
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}finally {
lock.unlock();
}
}
}
结果:
T001操作成功,当前余额:2000.0
T002操作成功,当前余额:-1000.0
T003操作成功,当前余额:0.0
T004操作成功,当前余额:-2000.0
T005操作成功,当前余额:0.0
账户:60001002,余额:0.0