栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

多线程-(4.2)LOCK

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

多线程-(4.2)LOCK

除了synchroinzed之外,JDK5之后还提供了更高级的锁 Lock。

实际上,Lock是一个interface,而实际上开发人员需要面对的,通常只有ReentrantLock和ReentrantReadWriteLock,下面就围绕这两个类进行讲解。

Lock(/lɑːk/) 接口的主要方法

1. void lock(): 执行此方法时, 如果锁处于空闲状态, 当前线程将获取到锁. 相反, 如果锁已经

被其他线程持有, 将禁用当前线程, 直到当前线程获取到锁.

2. boolean tryLock():如果锁可用, 则获取锁, 并立即返回 true, 否则返回 false. 该方法和

lock()的区别在于, tryLock()只是"试图"获取锁, 如果锁不可用, 不会导致当前线程被禁用,

当前线程仍然继续往下执行代码. 而 lock()方法则是一定要获取到锁, 如果锁不可用, 就一

直等待, 在未获得锁之前,当前线程并不继续向下执行.

3. void unlock():执行此方法时, 当前线程将释放持有的锁. 锁只能由持有者释放, 如果线程

并不持有锁, 却执行该方法, 可能导致异常的发生.

4. Condition newCondition():条件对象,获取等待通知组件。该组件和当前的锁绑定,

当前线程只有获取了锁,才能调用该组件的 await()方法,而调用后,当前线程将缩放锁。

5. getHoldCount() :查询当前线程保持此锁的次数,也就是执行此线程执行 lock 方法的次

数。

6. getQueueLength():返回正等待获取此锁的线程估计数,比如启动 10 个线程,1 个

线程获得锁,此时返回的是 9

7. getWaitQueueLength:(Condition condition)返回等待与此锁相关的给定条件的线

程估计数。比如 10 个线程,用同一个 condition 对象,并且此时这 10 个线程都执行了

condition 对象的 await 方法,那么此时执行此方法返回 10

8. hasWaiters(Condition condition):查询是否有线程等待与此锁有关的给定条件

(condition),对于指定 contidion 对象,有多少线程执行了 condition.await 方法

9. hasQueuedThread(Thread thread):查询给定线程是否等待获取此锁

10. hasQueuedThreads():是否有线程等待此锁

11. isFair():该锁是否公平锁

12. isHeldByCurrentThread(): 当前线程是否保持锁锁定,线程的执行 lock 方法的前后分

别是 false 和 true

13. isLock():此锁是否有任意线程占用

14. lockInterruptibly():如果当前线程未被中断,获取锁

15. tryLock():尝试获得锁,仅在调用时锁未被线程占用,获得锁

16. tryLock(long timeout TimeUnit unit):如果锁在给定等待时间内没有被另一个线程保持,

则获取该锁。

注:

从Lock中提供的基本API可以看到,它只负责获取锁和释放锁。如果需要实现类似wait()/notify()这种等待/通知的机制,还需要借助Condition接口。

Condition:

Condition接口提供了最基本的实现等待/通知机制的API 这里先介绍一些它最基本的API。

  • await():让当前线程进入WAITING状态,同时释放锁,
  • signal():通知某个处于WAITING状态的线程,可以继续获取锁执行。
  • signalAll():通知所有处于WAITING状态的线程,开始争抢锁然后执行。

ReentrantLock: (Reentrant: /riːˈentrənt/ ;(rui an chuan t);重入)
public class MyService {
 private Lock lock = new ReentrantLock();
//Lock lock=new ReentrantLock(true);//公平锁
 //Lock lock=new ReentrantLock(false);//非公平锁
 private Condition condition=lock.newCondition();//创建 Condition
 public void testMethod() {
 try {
 lock.lock();//lock 加锁
//1:wait 方法等待:
 //System.out.println("开始 wait");
 condition.await();
//通过创建 Condition 对象来使线程 wait,必须先执行 lock.lock 方法获得锁
//:2:signal 方法唤醒
condition.signal();//condition 对象的 signal 方法可以唤醒 wait 线程
 for (int i = 0; i < 5; i++) {
System.out.println("ThreadName=" + Thread.currentThread().getName()+ (" " + (i + 1)));
 }
 } catch (InterruptedException e) {
 e.printStackTrace();
 }
 finally
 {
 lock.unlock();
 }
 } }

ReentrantReadWriteLock:
class Cache {
    private Map map = new ConcurrentHashMap<>();

    private ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();

    
    public void put(String key, Object value){
        readWriteLock.writeLock().lock();
        try {
            System.out.println(key+"====正在签字: "+ value);
            //耗时操作
            try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) {e.printStackTrace(); }
            map.put(key, value);
            System.out.println("===签字完成===");
        } finally {
            readWriteLock.writeLock().unlock();
        }
    }

    
    public Object get(String key){

        Object result = null;
        readWriteLock.readLock().lock();
        try {
            System.out.println(key + "====正在看大家的签字:");
            //耗时操作
            try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) {e.printStackTrace(); }
            result = map.get(key);
            System.out.println(key+"===看完了===");
        } finally {
            readWriteLock.readLock().unlock();
        }
        return result;
    }
}

public class ReadWriteLockDemo {
    public static void main(String[] args) {
        Cache cache = new Cache();

        //写
        for (int i = 1; i <= 5; i++) {
            final int temp = i;
            new Thread(()->{
                cache.put("线程名"+temp, "数据"+temp);
            }, String.valueOf(i)).start();
        }

        //读
        for (int i = 1; i <= 5; i++) {
            final int temp = i;
            new Thread(()->{
                cache.get("线程名"+temp);
            }, String.valueOf(i)).start();
        }
    }
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/955992.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号