icode icode
首页
  • Android学习

    • 📁基础内容
    • 📺AndroidCore
    • 🎨Android-UI
    • 🏖️Components
    • 📊Fragment
    • 🔗网络操作
    • 🔏异步机制
    • 📦数据存储
    • 🗃️Gradle
  • 学习笔记

    • 『框架』笔记
    • 『Kotlin』笔记
    • 《Vue》笔记
    • 《Git》学习笔记
    • 『Bug踩坑记录』
  • ListView
  • RecyclerView
  • ViewPager
  • Java笔记

    • 🟠JavaSE
    • 🟢JavaWeb
    • 🔴JavaEE
    • ⚪JavaTopic
    • 🍳设计模式
  • 计算机基础

    • 📌计算机网络
    • 🔍数据结构
    • 📦数据库
    • 💻OS
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
  • 关于

    • 📫关于我
  • 收藏

    • 网站
    • 资源
    • Vue资源
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

iqqcode

保持对技术的探索实践与热爱
首页
  • Android学习

    • 📁基础内容
    • 📺AndroidCore
    • 🎨Android-UI
    • 🏖️Components
    • 📊Fragment
    • 🔗网络操作
    • 🔏异步机制
    • 📦数据存储
    • 🗃️Gradle
  • 学习笔记

    • 『框架』笔记
    • 『Kotlin』笔记
    • 《Vue》笔记
    • 《Git》学习笔记
    • 『Bug踩坑记录』
  • ListView
  • RecyclerView
  • ViewPager
  • Java笔记

    • 🟠JavaSE
    • 🟢JavaWeb
    • 🔴JavaEE
    • ⚪JavaTopic
    • 🍳设计模式
  • 计算机基础

    • 📌计算机网络
    • 🔍数据结构
    • 📦数据库
    • 💻OS
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
  • 关于

    • 📫关于我
  • 收藏

    • 网站
    • 资源
    • Vue资源
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • JavaSE

    • 面向对象

    • 常用API

    • 集合类

    • 多线程

      • Thread

        • 进程与线程
        • 黄牛卖票和模拟龟兔赛跑问题分析
        • 线程常用方法
        • 线程停止及守护线程
        • synchronized关键字解决线程安全问题
        • synchnized原理及优化
        • 线程间的通信
        • 死锁
        • Lock体系
          • 1. Lock体系
            • Lock接口
          • 2. Lock锁的使用
          • 3. Condition
          • 5. 使用synchronized还是Lock
        • ReentrantLock
        • 线程池使用
        • 线程池原理及配置
        • Java线程池的四种用法与使用场景
        • ThreadLocal
      • JUC

    • JDK8新特性

    • IO流

    • JVM

  • JavaWeb

  • JavaEE

  • JavaTopic

  • 设计模式

  • 计算机基础

  • Java后端
  • JavaSE
  • 多线程
  • Thread
iqqcode
2021-06-17
目录

Lock体系

# 1. Lock体系

# Lock接口

Lock----JDK5 基于Java语言实现的线程锁

Java中实现线程“锁”的方式:

  • synchronized
  • Lock

下面来看看Lock接口中定义了哪些方法

在这里插入图片描述

  1. void lock(); 获取锁
  2. void lockInterruptibly(); 获取锁的过程能够响应中断
  3. boolean tryLock(); 非阻塞式响应中断能立即返回,获取锁返回true反之为false
  4. boolean tryLock(long time,TimeUnit unit); 超时获取锁,在超时内或未中断的情况下能获取锁
  5. Condition newCondition(); 获取与lock绑定的等待通知组件,当前线程必须先获得了锁才能等待,等待会释放锁,再次获取到锁才能从等待中返回

Lock类相关介绍

  1. Lock重要的实现类:ReentrantLock 和 ReentrantReadWriteLock。
  2. Lock:定义了标准的Lock的api。
  3. ReentrantLock :重入锁(实现了AQS) 支持公平和非公平。
  4. ReentrantReadWriteLock:同ReentrantLock 在基础上支持读写分离适合多读少写的场景
  5. Condition:是需要与Lock配合使用的,提供多个等待集合,更精确的控制(底层是park/unpark机制)

可中断锁:在等待获取锁过程中可中断。注意是在等待锁过程中才可以中断,如果已经获取了锁,中断就无效。


# 2. Lock锁的使用

Lock是一个接口,就类似List和Set接口,具体的使用还是调用其实现类ReentrantLock(重入锁)

Lock实现类介绍

  1. 所的实现类:AQS(AbstractQueuedSynchronizer)、ReentrantLock、ReentrantReadWriteLock、CountDownLatch、Semphore。
  2. 其他多线程协作的场景: CyclicBarrier

在这里插入图片描述

package com.iqqcode.lock;

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

/**
 * @Author: Mr.Q
 * @Date: 2020-05-28 16:55
 * @Description:Lock锁
 */
class Sync implements Runnable {

    //实现Lock的接口来定义锁
    private Lock ticketsLock = new ReentrantLock();
    private int tickets = 20;

    @Override
    public void run() {
        while(true) {
            //需要对程序上锁
            try {
                //等同于synchronized(this)
                ticketsLock.lock();
                Thread.sleep(200);
                if(this.tickets >= 0) {
                    System.out.println(Thread.currentThread().getName() +
                            "还有" + this.tickets-- + "张票");
                }else {
                    break;
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                ticketsLock.unlock();
            }
        }
    }
}

public class LockSync {
    public static void main(String[] args) {
        Sync run = new Sync();
        new Thread(run,"黄牛A").start();
        new Thread(run,"黄牛B").start();
        new Thread(run,"黄牛C").start();
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

可以看出 Lock 可以实现和 synchronized 同样的功能

在这里插入图片描述



# 3. Condition

Condition:Lock体系的线程通信方式,类比Object类的 wait,notify;可以进一部提高效率,减少线程阻塞与唤醒带来的开销

await(): 释放Lock锁,将线程置入等待队列阻塞

signal(): 唤醒一个处于等待状态的线程

signalAll(): 唤醒所有线程

类比 wait() 和 notify( )

获取一个Lock锁的Condition队列:

Lock.newCondition : 每当调用一次,就产生一个新的Condition

使用详见👉 《6.线程间的通信》


# 5. 使用synchronized还是Lock

  1. Lock是显示锁,手动关闭,手动开启;synchronized是隐式锁,出了作用域自动释放

  2. Lock只能作用域代码块,而synchronized可以作用域代码块和方法上

  3. 使甪Lock锁JVM将花费较少的时间来调度线程,性能更好,并且具有更好的扩展性(提供更多的子类)

  4. 若无特殊的应用场景,推荐使用 synchronized,其使用方便(隐式的加减锁),并且由于 synchronized是 JVM层面的实现,在之后的 JDK还有优化

  5. 若要使用 公平锁,读写锁,超时锁等特殊场景,才会考虑使用 Lock

  6. Synchronized是可重入锁,不可以中断的,非公平;Lock是可重入锁,可以判断锁,非公平(可设置)

编辑 (opens new window)
上次更新: 2021/06/27, 10:49:09
死锁
ReentrantLock

← 死锁 ReentrantLock→

最近更新
01
匿名内部类
10-08
02
函数式接口
10-08
03
ARouter-Kotlin踩坑
10-05
更多文章>
Theme by Vdoing | Copyright © 2021-2023 iqqcode | MIT License | 备案号-京ICP备2021028793号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式
×