Lock锁基本的使用

最近有些许考试和一场面试的打扰,写博客的速度大不如前。而且最近眼疾泛滥,电脑看的时长也减少了许多。我这眼睛只要看久了电子屏幕就会连续几天干涩困乏,难道我真的不适合IT行业?但我也不想沦落成为楼盘销售人员。

Lock锁

切入正题,在JDK1.5后,Java提供了既synchronized和wait()、notify()之后第三种可以实现多线程同步的方法。Lock锁相较之前多线程同步控制方法而言,使用更加了灵活,当然,“灵活”一词也代表了你需要掌握的东西需要更多。
首先我们需要看一下ReentrantLock(重入锁)这个类的继承体系。

public class ReentrantLock implements Lock, Serializable

Serializable序列化接口我们不用去理会他,主要需要了解是Lock接口
下面是Lock接口的source文档

public interface Lock {
    void lock();

    void lockInterruptibly() throws InterruptedException;

    boolean tryLock();

    boolean tryLock(long var1, TimeUnit var3) throws InterruptedException;

    void unlock();

    Condition newCondition();
}
使用ReentrantLock实现同步

lock()方法:以阻塞的方式获得锁,如果当前没有获得对象的锁,那么就如同服务器端编程中的receive()方法一样,当前线程会一直等待,直到获得锁后返回。
unlock()方法:顾名思义,释放当前对象的锁。
案例代码:

public class ThreadTest04 implements Runnable{
    Lock lock = new ReentrantLock();
    @Override
    public void run() {
        lock.lock();
        for (int i = 0; i < 2; i++) {
            System.out.println(Thread.currentThread().getName()+": "+i);
        }
        lock.unlock();
    }

    public static void main(String[] args) {
        ThreadTest04 test = new ThreadTest04();
        Thread thread01 = new Thread(test);
        Thread thread02 = new Thread(test);
        Thread thread03 = new Thread(test);
        thread01.start();
        thread02.start();
        thread03.start();
    }
}

运行结果:

Thread-0: 0
Thread-0: 1
Thread-2: 0
Thread-2: 1
Thread-1: 0
Thread-1: 1

相比于之前锁相关对象而言,这里的对象锁是lock。调用lock.lock()后该线程就持有了“对象监视器”,其他线程只有等待当前锁被释放后再争抢。

使用Condition实现等待/通知

在synchronized关键字中可以使用wait()和notify()方法实现线程的等待与通知模式。在使用notify()、notifyAll()方法进行通知时,被通知的线程时JVM随机选择的。
在Lock机制中可以借助Condition对象,可以实现“选择性通知”。一个Lock对象可以创建多个Condition(对象监视器)实例。
在Object类中的wait()方法等同于Condition类中的await()方法。Object类中的notify()方法等同于Condition类中的singal()方法。Object类中的notifyAll()方法等同于Condition类中的signAll()方法。
代码案例:

public class ThreadTest04 implements Runnable{
    Lock lock = new ReentrantLock();
    Condition condition = lock.newCondition();
    @Override
    public void run() {
        lock.lock();
        System.out.println("开始等待时间:"+System.currentTimeMillis());
        System.out.println("线程等待");
        try {
            condition.await();
            //线程释放锁
            lock.unlock();
            System.out.println("线程锁释放了");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public void signal(){
        try {
            lock.lock();
            System.out.println("线程结束时间"+System.currentTimeMillis());
            condition.signal();
        } finally {
            lock.unlock();
        }
    }

    public static void main(String[] args) throws InterruptedException {
        ThreadTest04 test = new ThreadTest04();
        Thread thread = new Thread(test, "线程1");
        thread.start();
        Thread.sleep(1000);
        test.signal();
    }
}

执行结果

开始等待时间:1593438949647
线程等待
线程结束时间1593438950648
线程锁释放了
公平锁与非公平锁

公平锁:表示线程获取锁的顺序是按照线程加锁的顺序来进行分配的,即FIFO。
非公平锁:一种获取锁的抢占式机制,随机拿到锁的,和公平锁不一样的是不一定先来的先拿到锁,这种方式可能导致一些线程一直拿不到锁。

夜已经深了,目前先写个基础部分,当然Lock机制远远不止这些,后面我会进行扩展。再回

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值