当前位置: java基础教程 > 11-java多线程 > 阅读正文

Lock 锁

2021.2.10.   512 次   1296字

对于解决线程安全的另一种方式,是 Lock 锁

Lock 锁比 synchronized 性能更好,可以避免其他线程不断检测锁对象

1.导包

Lock 是一个接口类,无法直接创建,导入它和它的子类实现类

import java.util.Lock;
java.util.concurrent.locks.ReentrantLock;
2.构造方法

使用多态的方式构造

Lock l = new ReentrantLock();
3.方法

1.上锁

l.lock();

2.解锁

l.unlock();
4.例子

配合 try — catch — finally ,可以很好的解决线程安全问题

创建一个类,名称 RunnableImpl ,拷贝如下代码即可

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

/*
    卖票案例出现了线程安全问题
    卖出了不存在的票和重复的票

    使用步骤:
        1.在成员位置创建一个ReentrantLock对象
        2.在可能会出现安全问题的代码前调用Lock接口中的方法lock获取锁
        3.在可能会出现安全问题的代码后调用Lock接口中的方法unlock释放锁
 */
public class RunnableImpl implements Runnable{
    //定义一个多个线程共享的票源
    private  int ticket = 100;

    //1.在成员位置创建一个ReentrantLock对象
    Lock l = new ReentrantLock();

    //设置线程任务:卖票
    @Override
    public void run() {
        //使用死循环,让卖票操作重复执行
        while(true){
            //2.在可能会出现安全问题的代码前调用Lock接口中的方法lock获取锁
            l.lock();

            //先判断票是否存在
            if(ticket>0){
                //提高安全问题出现的概率,让程序睡眠
                try {
                    Thread.sleep(10);
                    //票存在,卖票 ticket--
                    System.out.println(Thread.currentThread().getName()+"-->正在卖第"+ticket+"张票");
                    ticket--;
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }finally {
                    //3.在可能会出现安全问题的代码后调用Lock接口中的方法unlock释放锁
                    l.unlock();//无论程序是否异常,都会把锁释放
                }
            }
        }
    }
    public static void main(String[] args) {
        //创建Runnable接口的实现类对象
        RunnableImpl run = new RunnableImpl();
        //创建Thread类对象,构造方法中传递Runnable接口的实现类对象
        Thread t0 = new Thread(run);
        Thread t1 = new Thread(run);
        Thread t2 = new Thread(run);
        //调用start方法开启多线程
        t0.start();
        t1.start();
        t2.start();
    }
}  

本篇完,还有疑问?

加入QQ交流群:11500065636 IT 技术交流群