一、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();
            }
        }
    }
}