一、Lock锁
虽然我们可以理解同步代码块和同步方法的锁对象问题,但是我们并没有直接看到在哪里上了锁,在哪里释放了锁,为了更清晰的表达如何加锁和释放锁,JDK5以后提供了一个新的锁对象Lock
Lock实现提供比使用synchronized方法和语句更广泛的锁定操作
二、Lock中提供了获得锁和释放锁的方法
1.void lock():获得锁
2.void unlock();释放锁
Lock由于是接口,不能直接实例化,这里采用它的实现类ReentrantLock来实例化
三、ReentrantLock的构造方法
ReentrantLock():创建一个ReentrantLock的实例
例如:之前的卖票案例就可以这样写
public class SellTicket implements Runnable {
//定义总张数
private int tickets = 100;
//定义Lock锁,要用它的实现类完成
Lock lock=new ReentrantLock();
@Override
public void run() {
while (true) {
//判断车票是否大于0
//加锁
lock.lock();
if (tickets > 0) {
System.out.println(Thread.currentThread().getName() + "卖出第" + tickets + "张车票");
tickets--;
//模仿出票
try {
sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//释放锁
lock.unlock();
}
}
}
为了避免出现有时候出现异常不能及时释放锁的情况,我们用try...finally来操作一下
package Demo041901;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import static java.lang.Thread.sleep;
public class SellTicket implements Runnable {
//定义总张数
private int tickets = 100;
//定义Lock锁,要用它的实现类完成
Lock lock=new ReentrantLock();
@Override
public void run() {
while (true) {
//判断车票是否大于0
try {
//加锁
lock.lock();
if (tickets > 0) {
System.out.println(Thread.currentThread().getName() + "卖出第" + tickets + "张车票");
tickets--;
//模仿出票
try {
sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}else {
break;
}
}finally {
//释放锁
lock.unlock();
}
}
}
}