java同步锁Lock

Laughing
2022-09-01 / 0 评论 / 953 阅读 / 搜一下 / 正在检测是否收录...

Java中Synchronized的用法中,我们介绍了通过Synchronized实现线程同步的机制。除了通过Synchronized实现线程同步之外,我们还可以通过同步锁(java.util.concurrent.locks.Lock)实现线程同步。
看下下面代码

package com.company.threadpackage;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class Apple implements Runnable {

    private int num = 50;
    private final Lock lock = new ReentrantLock();

    @Override
    public void run() {
        while (num > 0) {
            lock.lock();
            try {
                if (num > 0) {
                    System.out.println(Thread.currentThread().getName() + " 吃了编号为 " + num-- + " 的苹果");
                }
            }finally {
                lock.unlock();
            }
        }
    }
}

调用


        Apple apple = new Apple();
        for(int i=0;i<1000;i++){
            new Thread(apple,"apple"+i).start();
        }
  

查看控制台,可以看到,num始终是在顺序减少。

  • Lock 接口的实现允许锁在不同的作用范围内获取和释放,并允许以任何顺序获取和释放多个锁。
  • 常用的实现类ReentrantLock(可重入锁):java.util.concurrent.locks 包中,通常建议使用 finally 块来确保在必要时释放锁ReentrantLock 是可重入锁:当前持有该锁的线程能够多次获取该锁,无需等待(可以在递归算法中使用锁)

[typing]Lock 和 synchronized 的选择[/typing]

  • Lock是一个接口,而synchronized是Java中的关键字,synchronized是内置的语言实现
  • synchronized在发生异常时,会自动释放线程占有的锁,因此不会导致死锁现象发生;而Lock在发生异常时,如果没有主动通过unLock 去释放锁,则很可能造成死锁现象,因此使用Lock时需要在finally块中释放锁
  • Lock可以让等待锁的线程响应中断,而synchronized却不行,使用synchronized时,等待的线程会直等待下去,不能够响应中断
  • 通过Lock可以知道有没有成功获取锁,而synchronized却无法办到
  • Lock可以提高多个线程进行读操作的效率
  • 在性能上来说,如果竞争资源不激烈,两者的性能是差不多的,而当竞争资源非常激烈时(即有大量线程同时竟争),此时 Lock的性能要远远优于synchronized。所以说,在具体使用时要根据适当情况选择
0

评论 (0)

取消