首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Java8 Lock锁基本使用

Java8 Lock锁基本使用

什么是Lock锁?

Lock锁提供了的比synchronized关键字更加灵活的锁操作,是代码层面的锁操作。

为什么要使用Lock锁?

Lock锁和synchronized关键字的对比

synchronized关键字

获取锁无超时时间,未获取到则阻塞等待(占用cpu资源),且无法被中断非阻塞,

共享锁不支持

释放锁必须在当前代码块中,因为synchronized是以{}来锁住共享资源的

Lock锁

可以被中断,未获取到则排队,中断,可以自定义超时时间

读写锁ReadWriteLock支持

可以在任意位置释放锁(其他方法或者其他类)

概念普及

公平锁:保证每个线程都能获取到锁(排队先进来的先获取到锁),能够避免线程饥饿

非公平锁:谁抢到就是谁的,抢不到就排队

悲观锁:每次更新和读取都加锁,对于读多写少这种场景不利,适用于于写多读少的场景

乐观锁:更新失败则重试,适用一个标记位来控制,适用于多读的场景。

可重入锁:同一线程多次进入无需重新获取锁

共享锁(读锁):一个锁可以同时被多个线程拥有,ReentrantReadWriteLock的读锁为共享锁,写锁为排他锁

排他锁(写锁):独占锁,一个锁在某一时刻只能被一个线程占有,其它线程必须等待锁被释放之后才可能获取到锁,ReentrantLock就是排他锁。

public class LockTest {

// 这个必须放在成员变量或者作为方法参数进行传递。具体原因见后面代码分析

private final Lock lock = new ReentrantLock();

// 共享资源a

private int a = 0;

public static void main(String[] args) throws InterruptedException {

LockTest lockTest = new LockTest();

for (int i = 0; i < 10; ++i) {

// 模拟10个线程对 a进行++

new Thread(() -> {

for (int j = 0; j < 10000; ++j) {

lockTest.testLock();

}

}).start();

}

// 防止因为主线程结束,导致程序运行失败

Thread.sleep(5000);

System.out.println(lockTest.a);

}

public void testLock() {

try {

// 这块加锁也应该放到for循环外面。放里面会有性能问题。每+1就释放锁,

// 正常用该是+n然后等待cpu调度,然后释放锁

lock.lock();

++a;

} finally {

lock.unlock();

}

}

}

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20200705A06RBC00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券
http://www.vxiaotou.com