Java并发--同步锁Lock

本文深入探讨了Java 1.5引入的Lock接口及其特性,包括可操作的锁获取与释放、可中断的锁获取及超时获取锁等功能。通过对比synchronized关键字,详细解析Lock接口的API和使用方式,并提供了一个抢票案例来展示其实际应用。

Lock接口

在Java1.5之后,并发包中新增了Lock接口(以及相关实现类)用来实现锁功能,它提供了与synchronized关键字类似的同步功能,只是在使用时需要显示地获取和释放锁。虽然它缺少了(通过synchronized块或者方法所提供的)隐式获取释放锁的便捷性,但是却拥有了锁获取与释放的可操作性、可中断的获取锁以及超时获取锁等多种synchronized关键字所不具备的同步特性。

Lock的使用非常简单。如下所示:

Lock lock = new ReentrantLock();
lock.lock();
try{

}finally{
	lock.unlock();
}

在finally块中释放锁,目的是保证在获取到锁之后,最终能够被释放。

不要将获取锁的过程写在try块中,因为如果在获取锁(自定义的实现)时发生了异常,异常抛出的同时,也会导致锁无故释放!

Lock接口提供的synchronized关键字所具备的主要特性如下:

特性描述
尝试非阻塞地获取锁当前线程尝试获取锁,如果这一时刻没有被其他线程获取到,则成功获取并持有锁
能被中断地获取锁与synchronized不同,获取到锁的线程能够响应中断,当获取到锁的线程被中断时,中断异常将会被抛出,同时锁会释放
超时获取锁在指定的截止时间之前获取锁,如果截止时间到了仍旧无法获取锁,则返回

Lock接口的API:

方法描述
void lock()获取锁,调用该方法当前线程将会获取锁,当锁获取后,从该方法返回
void lockInterruptibly() throws InterruptedException可中断地获取锁,和lock方法的不同之处在于该方法会响应中断,即在锁的获取中可以中断当前线程
boolean tryLock()尝试非阻塞的获取锁,调用该方法后立刻返回,如果能够获取则返回true,否则返回false
boolean tryLock(long time, TimeUnit unit) throws InterruptedException超时的获取锁,当前线程在以下3种情况下会返回:
1. 当前线程在超时时间内获得了锁
2. 当前线程在超时时间内被中断
3. 超时时间结束,返回false
void unlock()释放锁
Condition new Condition()获取等待通知组件,该组件和当前线程的锁绑定,当前线程只有获得了锁,才能调用该组件的wait()方法,而调用后,当前线程将释放锁

模拟一个简单的抢票案例

package pers.zhang.juc.part1;

import sun.security.krb5.internal.Ticket;

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

/**
 * @author zhang
 * @date 2020/1/17 - 19:54
 */
public class TestLock {
    public static void main(String[] args) {
        TrainTicket ticket = new TrainTicket();

        new Thread(ticket, "1号窗口").start();
        new Thread(ticket, "2号窗口").start();
        new Thread(ticket, "3号窗口").start();
    }
}

class TrainTicket implements Runnable{

    private int tick = 100;

    private Lock lock = new ReentrantLock();//Lock的实现类

    @Override
    public void run() {
        while(true){

            lock.lock(); //上锁

            try{
                if(tick > 0){
                    try {
                        Thread.sleep(200);
                    } catch (InterruptedException e) {
                    }

                    System.out.println(Thread.currentThread().getName() + " 完成售票,余票为:" + --tick);
                }
            }finally{
                lock.unlock(); //释放锁
            }
        }
    }

}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值