常用锁简介

  • 独享锁

    也叫排他锁该锁每次只能被一个线程持有. ReentrantReadWriteLock的写锁 ,synchronized

  • 共享锁

    该锁可以被多个线程持有.ReentrantLock,ReentrantReadWriteLock 里的读锁时共享锁

    独享锁与共享锁都是通过AQS来实现的

  • 互斥锁

    再访问共享资源之前进行加锁操作,访问完之后进行解锁操作.加锁后,其他线程想要获取资源会被阻塞,指定当前线程解锁

  • 读写锁

    读锁是共享锁,写锁是互斥(排他)锁.

  • 乐观锁

    假设最好的情况下,每次拿数据的时候都认为别的线程不会修改,所以不会上锁.在更新的时候会判断期间有没有别的线程更新这个数据.一般使用版本号或者CAS算法实现.多用于读类型的应用.列入AtomicInteger

  • 悲观锁

    假设最坏的情况下,每次拿数据的时候都认为会被别的线程修改,所以每次拿数据的时候会上锁,这样别的线程拿数据的时候会被阻塞.ReentrantLock,与synchronized都属于悲观锁

  • 可重入锁

    当一个线程在同一个对象内可以重复递归调用的锁,外层使用锁后,不需要释放内层仍然可以使用,且不发生死锁情况.可重入锁的意义就是防止放生死锁 synchronizedReentrantLock都是可重入锁

public abstract class Test2 {
​
    // 当method1调用method2时候,线程可以再次获取锁
    public synchronized void method1(){
        method2();
    }
​
    public synchronized  void method2(){
​
    }
}
  • 不可重入锁

    与可重入锁相反.同一个线程中当eat()方法调用sleep()方法时不释放锁,线程会一直处于自旋状态.此时放生死锁,等待自己释放锁,在区获取锁调用sleep()方法.

    ​
    public class Test2 {
        UnReentrantLock unReentrantLock = new UnReentrantLock();
        public static void main(String[] args) {
            Test2 test2 = new Test2();
            new Thread(()->{
                test2.eat();
            }).start();
        }
    ​
        public void eat(){
            unReentrantLock.lock();
            System.out.println("吃饭");
            //如果不释放该锁,线程会一直循环自旋,放生死锁
            //unReentrantLock.unlock();
            sleep();
        }
        public void sleep(){
            unReentrantLock.lock();
            System.out.println("睡觉");
            //unReentrantLock.unlock();
        }
    }
    /*
     *不可重入自旋锁
     */
    class UnReentrantLock{
        private AtomicReference<Thread> reference = new AtomicReference<>();
    ​
        public void lock() {
            Thread current = Thread.currentThread();
            // 自旋
            for (; ; ) {
                if (reference.compareAndSet(null, current)) {
                    return;
                }
            }
        }
        public void unlock() {
            Thread current = Thread.currentThread();
            reference.compareAndSet(current, null);
        }
    }

  • 自旋锁

    当一个线程尝试获取锁的时候,如果该锁被其他线程占用,这个线程会循环等待锁释放,指定获取到锁才退出

    1 自旋锁会让线程一直处于活跃状态,线程不会进入阻塞状态,避免了CPU上下文切换.如果线程过多会造成CPU高耗.

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值