锁的相关概念介绍
Posted xhy-shine
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了锁的相关概念介绍相关的知识,希望对你有一定的参考价值。
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,分别用来实现公平与否
以上是关于锁的相关概念介绍的主要内容,如果未能解决你的问题,请参考以下文章