zoukankan      html  css  js  c++  java
  • java并发编程:锁的相关概念介绍

    理解同步,最好先把java中锁相关的概念弄清楚,有助于我们更好的去理解、学习同步。java语言中与锁有关的几个概念主要是:可重入锁、读写锁、可中断锁、公平锁

    一、可重入锁

    synchronized和ReentrantLock都属于可重入锁,当前加锁的程序调用了一个持有当前锁对象的子程序不会发生阻塞,代码如下

    public synchronized void method2(){
        System.out.println("method2");
    }
    public synchronized void method1(){
        System.out.println("method1");
        method2();
    }

    执行method1()方法,获取锁,然后又调用同步方法method2(),这个时候线程不需要申请method2()的锁,可以直接执行

    如果synchronized不具备可重入性,线程A持有对象锁,进入method1方法,这个时候就要重新申请锁,但是这个锁其实就是线程A进入method1方法持有的锁,这样的话,线程A会一直等待一个永远获取不到的锁,所以synchronized和Lock都具备可重入性

    二、读写锁

    读写锁是将对一个资源的访问分成了两个锁:读锁和写锁

    读写锁中、读读不互斥、只有涉及到写锁才互斥

    ReadWriteLock是读写锁的根接口,实现类是ReentrantReadWriteLock(他们并没有实现Lock接口)

    通过readLock()获取读锁、writeLock()获取写锁

    三、可中断锁

    就是可以响应中断的锁。synchronized属于不可中断锁,Lock则是可中断锁

    如果线程A正在执行锁包住的代码,线程B等待获取该锁,有可能等待时间太长,线程B想去做别的事,我们可以让他中断自己或者在别的线程中断他。lock类使用lockInterruptibly()方法来实现可中断性,代码如下:

    package com.xhy.lock;
    
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    
    public class LockInterruptTest {
    
        private Lock lock = new ReentrantLock();
    
        public static void main(String[] args) {
            LockInterruptTest test = new LockInterruptTest();
            MyThread myThread1 = new MyThread(test);
            MyThread myThread2 = new MyThread(test);
            myThread1.start();
            myThread2.start();
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            myThread2.interrupt();
         // 处于等待中的线程2可以被正常终端(只有在调用lockInterruptibly()方法的情况下) } public void insert() throws InterruptedException { lock.lockInterruptibly(); // lock.lock(); try { System.out.println(Thread.currentThread().getName() + "获得了锁"); while (true){ } }finally { System.out.println(Thread.currentThread().getName() + "执行了finally"); lock.unlock(); System.out.println(Thread.currentThread().getName() + "释放了锁"); } } } class MyThread extends Thread{ private LockInterruptTest test; public MyThread(LockInterruptTest test){ this.test = test; } @Override public void run() { try { test.insert(); } catch (InterruptedException e) { System.out.println(Thread.currentThread().getName() + "中断"); } } }

    运行结果如下

    四、公平锁

    公平锁就是排队来获取锁,这个队是请求的顺序,不能抢占。非公平锁不能保证获取锁的顺序是按照请求锁的顺序来的。这样可能有的线程很难获取到锁,或者永远获取不到,哈哈

    synchronized属于非公平锁,对ReentrantLock和ReentrantReadWriteLock,它们默认情况下也不是公平锁,通过构造方法可以指定,代码如下:

    /**
     * Creates an instance of {@code ReentrantLock} with the
     * given fairness policy.
     *
     * @param fair {@code true} if this lock should use a fair ordering policy
     */
    public ReentrantLock(boolean fair) {
        sync = fair ? new FairSync() : new NonfairSync();
    }
    /**
     * Creates an instance of {@code ReentrantLock} with the
     * given fairness policy.
     *
     * @param fair {@code true} if this lock should use a fair ordering policy
     */
    public ReentrantLock(boolean fair) {
        sync = fair ? new FairSync() : new NonfairSync();
    }

    它们里面定义了两个静态内部类,一个是NoFailSync,一个是FairSync,分别用来实现公平与否

     

  • 相关阅读:
    Java方法命名之“由简入繁”原则
    设置Tomcat的字符编码
    MyBatis之会话Session原理
    SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@1fa5519] was not registered for synchronization because synchronization is not active
    python3 驱动 PyMySQL
    win 7 64 安装 MondgoDB 3.4
    Python
    win 7 64 安装 tensorflow
    俞敏洪:2017年上半年我的阅读书单和笔记 转
    阿里巴巴开源产品列表 转
  • 原文地址:https://www.cnblogs.com/xhy-shine/p/10785645.html
Copyright © 2011-2022 走看看