资讯专栏INFORMATION COLUMN

java并发编程学习之显示锁Lock

zone / 1553人阅读

摘要:显示锁和内置锁内置锁优势代码简洁不会因为没释放锁,导致锁泄露。显示锁优势灵活性强,锁的获取可以被中断,可以尝试获取锁。接口接口主要方法如下获取锁尝试获取锁,表示未加锁的情况。会进行抢锁操作,如果获取不到锁,也会进入阻塞队列等到唤醒。

显示锁和内置锁 内置锁(Synchronized)优势

代码简洁

不会因为没释放锁,导致锁泄露。

显示锁(Lock)优势

灵活性强,锁的获取可以被中断,可以尝试获取锁。

读多写少等场景。

用法

能用内置锁就用内置锁,不能用内置锁,才考虑用显示锁。

Lock接口

接口主要方法如下:

lock():获取锁

tryLock():尝试获取锁,true表示未加锁的情况。

unlock():释放锁

newCondition():创建一个Condition

Condition接口

接口主要方法如下:

await():等待,类似wait方法

signal():唤醒,类似notify方法

signalAll():唤醒全部,类似notifAll方法

使用形式
Lock lock = new ReentrantLock();
....
lock.lock();//获取锁
try{
    //业务逻辑
}finally{
    lock.unlock();//这边要注意释放,不然会导致锁泄露
}
示例
public class LockDemo {
    Lock lock = new ReentrantLock();
    static int num = 0;

    public void addNum(int value) {
        lock.lock();
        try {
            int temp = num;
            num = num + value;
            Thread.sleep(100);
            System.out.println(value + "+" + temp + "=" + num);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    static class AddThread1 extends Thread {
        LockDemo lockDemo;

        public AddThread1(LockDemo lockDemo) {
            this.lockDemo = lockDemo;
        }

        @Override
        public void run() {
            lockDemo.addNum(1);
        }
    }

    static class AddThread2 extends Thread {
        LockDemo lockDemo;

        public AddThread2(LockDemo lockDemo) {
            this.lockDemo = lockDemo;
        }

        @Override
        public void run() {
            lockDemo.addNum(2);
        }
    }


    public static void main(String[] args) {
        LockDemo lockDemo = new LockDemo();
        AddThread1 addThread1 = new AddThread1(lockDemo);
        AddThread2 addThread2 = new AddThread2(lockDemo);
        addThread1.start();
        addThread2.start();
    }
}

运行结果如下:

结果显示,跟之前synchronized结果是一样的,加锁解锁成功

公平锁和非公平锁

公平锁:先进来的线程先执行

非公平锁:后进来的线程可能先执行,效率较高。会进行抢锁操作,如果cas获取不到锁,也会进入阻塞队列等到唤醒。

ReentrantLock

构造参数有两个,默认是非公平锁,如果传参是true,则是公平锁。

public ReentrantLock() {
    sync = new NonfairSync();
}
public ReentrantLock(boolean fair) {
    sync = fair ? new FairSync() : new NonfairSync();
}

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/75572.html

相关文章

  • java并发编程习之再谈公平和非公平

    摘要:在并发编程学习之显示锁里有提过公平锁和非公平锁,我们知道他的使用方式,以及非公平锁的性能较高,在源码分析的基础上,我们看看和的区别在什么地方。而非公平锁直接尝试获取锁。 在java并发编程学习之显示锁Lock里有提过公平锁和非公平锁,我们知道他的使用方式,以及非公平锁的性能较高,在AQS源码分析的基础上,我们看看NonfairSync和FairSync的区别在什么地方。 lock方法 ...

    warkiz 评论0 收藏0
  • java并发编程习之AQS

    摘要:原理全称,当线程去获取资源的时候,会根据状态值来判断是否有锁,如果有锁,则加入到链表,链表里的线程,通过自旋,判断资源是否已经释放,如果释放,则获取资源。 原理 全称AbstractQueuedSynchronizer,当线程去获取资源的时候,会根据状态值state来判断是否有锁,如果有锁,则加入到链表,链表里的线程,通过自旋,判断资源是否已经释放,如果释放,则获取资源。 AQS结构 ...

    Tikitoo 评论0 收藏0
  • java并发编程习之ConcurrentHashMap(JDK1.7)

    摘要:之前中提过,并发的时候,可能造成死循环,那么在多线程中可以用来避免这一情况。默认,当容量大于时,开始扩容并发数,默认,直接影响和的值,以及的初始化数量。初始化的数量,为最接近且大于的办等于的次方的值,比如,数量为,,数量为。 之前HashMap中提过,并发的时候,可能造成死循环,那么在多线程中可以用ConcurrentHashMap来避免这一情况。 Segment Concurrent...

    piglei 评论0 收藏0
  • java并发编程习之线程的生命周期-wait,notify,notifyall(六)

    摘要:不释放持有的锁,释放锁。在调用方法前,必须持有锁,调用唤醒,也要持有锁。休眠一定时间后,进入就绪状态。这两个都能被方法中断当前状态。用法方获取锁判断条件,不满足继续满足执行其他业务方获取锁改变条件通知为什么是而不是会一直循环,直到条件满足。 sleep和wait sleep是Thread类的方法,wait是Object的方法。 sleep可以到处使用,wait必须是在同步方法或者代码...

    Terry_Tai 评论0 收藏0
  • java并发编程习之cas(一)

    摘要:线程把的值放在中。线程执行,得到的为。,,独占锁,会导致其他所有需要锁的线程挂起,等待持有锁的线程释放锁。可见性,不保证原子性。乐观锁,不适用锁的情况下实现多线程的变量同步。性能问题在并发量较高的情况下,如果一直不成功,会一直增加的开销。 cas原理 cas全称Compare and swap,比较和交换的意思。原子操作,需要硬件的支持。三个基本操作数:内存地址V,旧的预期值A,要修改...

    ConardLi 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<