《java多线程编程核心技术》第四章笔记

介绍Lock,可以代替synchronized关键字,大量的并发包使用了lock。

  • ReentrantLock类
  • ReentrantReadWriteLock 类

1、基本用法

通过lock和unlock进行上锁和解锁

Lock lock = new ReentrantLock();
void method(){
lock.lock();
//代码巴拉巴拉巴拉
locak.unlock();
}

2、condition用于通知

Lock lock = new ReentrantLock();
Condition condition = lock.newCondition();

//等待

void method(){
lock.lock();
condition.await();
lock.unlock();
}

//通知
void method(){
lock.lock();
condition.signal();
lock.unlock();
}

针对不同线程,可以建立多个condition。实现通知部分线程

构建Lock时,传递boolean值可以设置公平锁和不公平锁

lock = new ReentrantLock(false); // 不公平

3、方法getHoldCount、getQueueLength、getWaitQueueLength

  • getHoldCount:查询持有lock的线程的个数(线程内可以套用线程,因此lock块内也可以套用lock)
  • getQueueLength: 返回等待lock的线程的个数
  • getWaitQueueLength(Condition condition):返回condition.await()(等待notify)的线程个数

4、方法hasQueuedThread、hasQueuedThreads、hasWaiters

  • lock.hasQueueThread(Thread thread): 查询指定的线程是否在等待获取此锁
  • lock.hasQueuedThreads():查询是否有线程等待此锁
  • lock.hasWaiters(Condition condition):查询是否有线程正在等待和此condition相关。
  • lock.getWaitQueueLength(Condition condition):查询等待此condition的线程个数

5、方法isFair、isHeldByCurrentThread、isLocked

  • lock.isFair(): 判断锁lock是否是公平锁
  • lock.isHeldByCurrentThread():判断当前线程是否持有lock
  • lock.isLocked():判断lock是否被锁定

6、lockInterruptibly、tryLock、tryLock(long timeout,TimeUnit unit)

  • lock.lockInterruptibly(): 如果当前线程没有被中断,则获取这个锁,否则抛出异常。
  • lock.tryLock():如果lock没有被线程获取,那么当前线程就获取该锁。
  • lock.tryLock(time,timeUnit):等待time,如果time期间lock都没有被锁定,那么获取该锁。

7、awaitUninterruptiby()

如果进程在调用condition.await()时被其他进程interrupt,那么就会引发异常,如果调用的是condition.awaitUninterruptiby(),那么就不会有异常发生。

8、awaitUntil(Calendar calendar) 规定时间内会自动唤醒

9、实现线程按序执行

import javax.security.auth.Subject;
import java.util.*;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;


public class Main {

    volatile private static int nextPrintWho = 1;
    private static ReentrantLock lock = new ReentrantLock();
    final private static Condition conditionA = lock.newCondition();
    final private static Condition conditionB = lock.newCondition();

    public static void main(String[] args) {
        Thread threadA = new Thread(){
            @Override
            public void run() {
                try{
                    lock.lock();
                    while (nextPrintWho != 1)
                        conditionA.await();
                    for (int i = 0; i < 3; i++) {
                        System.out.println("ThreadA: " + i);
                    }
                    nextPrintWho = 2;
                    conditionB.signalAll();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }finally {
                    lock.unlock();
                }
            }
        };
        Thread threadB = new Thread(){
            @Override
            public void run() {
                try{
                    lock.lock();
                    while (nextPrintWho != 2)
                        conditionB.await();
                    for (int i = 0; i < 3; i++) {
                        System.out.println("ThreadB: " + i);
                    }
                    nextPrintWho = 1;
                    conditionA.signalAll();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }finally {
                    lock.unlock();
                }
            }
        };

        Thread[] aArray = new Thread[5];
        Thread[] bArray = new Thread[5];
        for (int i = 0; i < 5; i++) {
            aArray[i] = new Thread(threadA);
            bArray[i] = new Thread(threadB);
            aArray[i].start();
            bArray[i].start();
        }
    }
}

10、更高效的lock – ReentrantReadWriteLock

ReentrantReadWriteLock提供了读锁,写锁。
只有写锁之间互斥,读锁和写锁之间互斥。其他锁之间共享。

ReentrantReadWriteLock lock = new ReentrantReadWriteLock();

//读锁
lock.readLock.lock();
lock.readLock.unlock();

//写锁
lock.writeLock.lock();
lock.writeLock.unlock();
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值