`

锁的使用

 
阅读更多

锁用于解决多线程对共享资源的同时访问,而引起的非线程安全问题:某一时该只有一条线程可以访问共享资源,达到了线程安全的目的,但同时也限制了并发处理的速度。

 

锁的分类:

同步锁: synchronized 是java 内置的语法

可重入锁:ReentrantLock  是一个java类

读写锁:ReentrantReadWriteLock 是一个java类

 

 

锁定的范围:

 由于锁使线程互斥访问,未获得锁的线程会阻塞,限制了并发处理的速度,因此线程应该锁定尽量小的范围及尽快的释放锁。

 

 比如一家企业,有10个厕所,每个厕所有5个坑,每个员工都要上厕所,厕所的同一个坑不可能由多人共同使用,每个员工相当于一线线程,茅坑相当于共享资源,因此需要多个员工之间互斥使用同一个茅坑。

 

 错误的锁定范围:

    10个厕所:意味着 某个员工使用某个茅坑时,所有厕所都不能使用,严重浪费资源,影响并发使用率。 

    每个厕所:意味着 某个员工使用某个茅坑时,该厕所不能被别人使用,其他9个厕所允许9个人分别使用,浪费资源,影响并发使用率。

    

 正确的锁定范围:   

    每个茅坑:意味着 某个员工使用某个茅坑时,该茅坑不能被别人使用,其他49个茅坑允许49个人分别使用。

    

java中的锁定对象:

synchronized的锁定对象:

  语法:synchronized(被锁定对象)  或 在方法签名上声明

  全局锁定:Class对象,static 对象及方法,singleton 实例,equals相等的String对象

  部分锁定:某个多例类的实例,不同实例由不同的线程同时访问。

  

public class Test {
 
   public synchronized  void kk(){//做用于方法,锁定当前实例,不同实例间不影响
 
  }
  public static synchronized void ww(){//做用于静态方法锁定的是Class对象
 
  }
  public void t(Object obj){
    synchronized(obj){//锁定指定对象
     //
    }
  }
  public void f( ){
     synchronized(this){//锁定当前实例
     //
  }
 }
}

 

 

 

 

  

ReentrantLock 锁定对象:

同一个ReentrantLock实例,不同实例可由不同线程同时访问。

  用法:

  

class X {
   private final ReentrantLock lock = new ReentrantLock();
   public void m() { 
     lock.lock();  // block until condition holds
     try {
       // ... method body
     } finally {
       lock.unlock()
     }
   }
 }

 

 

 

  

ReentrantReadWriteLock          

readLock  共享锁,占用锁时,同一个ReentrantReadWriteLock实例的writeLock,被阻塞,同一个ReentrantReadWriteLock实例的readLock可以同时访问。

writeLock 独占锁,占用锁时,同一个ReentrantReadWriteLock实例的writeLock和readLock阻塞,直至锁被释放,不同实例可由不同线程同时访问

 

 

                                 

      

  

锁的释放: 

  1 代码执行完成,退出锁定

  2.由于条件不足,而无法继续执行,主动释锁定,等待条件满足,当条件满足时,需要另一条线程唤醒等待线程,唤醒的线程争得锁之后主动释放锁的代码之后执行

 

 A.synchronized

 1.synchronized方法或代码块执行完成,而释放锁

   2.synchronized:被锁定对象.wait()方法被调用时释放锁而等待,  被唤醒方式:被锁定对象.notifyAll()(这两个方法需要执行锁时才能执行)

  B. ReentrantLock

    1.代码执行完成后,ReentrantLock.unlock()代码被调用,而释放锁

    2.由ReentrantLock.newCondition()生成Condition对象的await()方法被调用时,释放锁而等待,被唤醒方式同一个Condition对象的signalAll方法被调用。(这两个方法需要执行锁时才能执行)

  C.ReentrantReadWriteLock

    1.代码执行完成后,ReentrantReadWriteLock的readLock 或writeLock 对象的unlock方法被调用,而释放锁

    2.readLock 不支持由条件不足释放锁定而等待条件满足。writeLock.newCondition()生成Condition对象的await()方法被调用时,释放锁而等待,被唤醒方式同一个Condition对象的signalAll方法被调用。(这两个方法需要执行锁时才能执行)

    

class RWDictionary {
    private final Map<String, Data> m = new TreeMap<String, Data>();
    private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
    private final Lock r = rwl.readLock();
    private final Lock w = rwl.writeLock();
 
    public Data get(String key) {
        r.lock();
        try { return m.get(key); }
        finally { r.unlock(); }
    }
    public String[] allKeys() {
        r.lock();
        try { return m.keySet().toArray(); }
        finally { r.unlock(); }
    }
    public Data put(String key, Data value) {
        w.lock();
        try { return m.put(key, value); }
        finally { w.unlock(); }
    }
    public void clear() {
        w.lock();
        try { m.clear(); }
        finally { w.unlock(); }
    }

 

 

信号量Semaphore :

 

一般用于限制对某些资源固定数量的访问。 

Semaphore维护了N个的许可,某线程通过acquire()获取一个许可或acquire(int permits) 获取多许可,如果许可数量N大于线程要求的许可数,线程得到许可并可以继续执行。

否则线程阻塞,等待某线程释放许可。

某线程释放许可,许可数量增加并唤醒被阻塞的线程,阻塞线程唤醒后再试着获取许可,获取成功则继续执行否则再次阻塞。

 

    

不使用锁解决非线程安全问题(有一定局限性):

  实现方式:一般使用CAS (compare and swap)  实现

  使用场景:AtomicLongFieldUpdater  对volatile long 字段进行原子更新

            AtomicReferenceFieldUpdater 对 volatile 字段进行原子更新   

            AtomicReference 原子方式更新的对象引用

      

  示例:ConcurrentLinkedQueue

   

boolean casNext(Node<E> cmp, Node<E> val) {
            return nextUpdater.compareAndSet(this, cmp, val);
    }
    
     public boolean offer(E e) {
        if (e == null) throw new NullPointerException();
        Node<E> n = new Node<E>(e, null);
        for (;;) {
            Node<E> t = tail;
            Node<E> s = t.getNext();
            if (t == tail) {
                if (s == null) {
                    if (t.casNext(s, n)) {
                        casTail(t, n);
                        return true;
                    }
                } else {
                    casTail(t, s);
                }
            }
        }
    }
    
     private static final
            AtomicReferenceFieldUpdater<Node, Node>
            nextUpdater =
            AtomicReferenceFieldUpdater.newUpdater
            (Node.class, Node.class, "next");

 

            

 

 

  

分享到:
评论

相关推荐

    Hasp加密锁使用手册

    "Hasp加密锁使用手册" Hasp加密锁是一种广泛应用于软件保护和加密的技术,通过使用Hasp加密锁,可以对软件进行加密保护,防止反编译和非法使用。本手册将详细介绍Hasp加密锁的使用方法和原理。 一、Hasp加密锁类型...

    电子密码锁使用说明

    《电子密码锁使用说明》 电子密码锁是一种现代化的安全设备,广泛应用于家庭、办公室和商业场所,以提供方便且安全的门禁管理。本使用说明将详细介绍电子密码锁的各个部分,安装步骤,操作方法以及相关性能指标。 ...

    Redis 分布式锁使用

    **Redis 分布式锁使用详解** 在分布式系统中,数据一致性是至关重要的,而实现这一目标的一个关键组件就是分布式锁。Redis,作为一个高性能的键值存储系统,由于其丰富的数据结构和优秀的性能,常被用来实现分布式...

    java常用锁使用demo工程

    "java常用锁使用demo工程"是一个实践项目,旨在帮助开发者理解并熟练掌握Java中的锁机制。在这个工程中,我们可能会看到各种锁的实例,如内置锁(synchronized)、显式锁(java.util.concurrent.locks包中的Lock接口...

    redis分布式锁使用实例.rar

    通过学习和实践这个“redis分布式锁使用实例”,你可以深入理解如何在实际项目中使用 Redis 和 Redisson 来实现高效且可靠的分布式锁,这对于处理分布式系统中的并发控制至关重要。同时,这也为你提供了设计和实现...

    Dahua大华V7系列智能锁使用说明书.pdf

    Dahua大华V7系列智能锁使用说明书.pdf

    oracle数据库锁使用

    4. 行级排它锁(RX锁):行级排它锁通常在`INSERT`、`UPDATE`或`DELETE`语句执行时使用,它比行级锁限制更多,因为它阻止其他事务加排它锁。其他事务可以进行查询、插入、更新和删除操作,但不能加排它锁。 Oracle...

    智能锁使用教程1111

    智能锁使用教程

    物流公司在途系统电子锁使用管理规定.pdf

    物流公司在途系统电子锁使用管理规定.pdf

    多线程编程——互斥锁使用(Jack_pthread_mutex_test.rar)

    多线程编程:互斥锁使用。 打包文件包含两个文件:c文件源代码、Makefile文件,运行环境在Ubuntu14.04下,使用自带的gcc编译器,同学们只需将文件夹复制到某一目录下之后在终端执行:1.“make”生成“test”可执行...

    CA锁使用方法.pdf

    由于这个CA锁可能与湖北省发放的其他锁驱动存在冲突,因此建议不要在同台电脑上同时使用。下面是详细的使用步骤: 1. **下载CA驱动**: 进入荆门公共资源交易网的“网上交易—网员管理—企业信息库—附件下载”...

    Informix查锁方法

    - **如果事先对锁信息一无所知**,可以使用`onstat -k | grep X`命令来获取锁的相关信息。例如,执行`onstat -k`命令后,我们可以看到以下锁的信息输出: ``` Locks address wtlist owner lklist type tblsnum ...

    中国结智能锁CK808A带显示使用安装说明书.pdf

    中国结智能锁CK8080A玻璃门专用指纹锁说明书

    线程和线程锁的使用源码例子

    以下是一个简单的互斥锁使用例子: ```cpp #include // 全局互斥锁 HANDLE g_hMutex = NULL; void ThreadFunction() { // 获取互斥锁,如果已被其他线程持有,则阻塞当前线程 if (WaitForSingleObject(g_...

    TENON亚太天能指纹锁产品通用说明书.pdf

    《亚太天能指纹锁产品通用说明书》详细解读 亚太天能作为智能锁领域的知名品牌,其指纹锁产品以其安全性和便捷性赢得了市场的广泛认可。本文将深入解析该产品的使用手册,帮助用户更好地理解和操作这款高科技安全...

    磁力锁使用(安装)方法

    1.常见的磁力锁安装方法:简易安装、ZL支架安装、UL支架安装 2.常见的磁力锁接线方法,带反馈信号等 3.文档为说明书纸质扫描件

Global site tag (gtag.js) - Google Analytics