heima并发7---reentrantLock预习--120-127

电子书:

锁池(对象头),等待池(waitset)。

-------------------------------------04---71-----------------------------------------

测试可重入:

代码:

测试可以重入的:

注意a调用b,此时a锁,b也锁,是可重入的锁。就是我在一个加锁的方法里面调用另一个加锁的方法,是可以调用的。

-------------------------------------04   72--------------------------------------------

测试可打断:

没有被打断的情况。

package cn.itcast.test;

import lombok.extern.slf4j.Slf4j;

import java.sql.Time;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;

import static cn.itcast.n2.util.Sleeper.sleep;

@Slf4j(topic = "c.Test22")
public class Test22 {
    private static ReentrantLock lock = new ReentrantLock();
    public static void main(String[] args) {
        Thread t1 = new Thread(() -> {
            System.out.println("test");
            try {
                if (! lock.tryLock(2, TimeUnit.SECONDS)) {
                    System.out.println("获取不到锁 in time");
                    return;
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
                System.out.println("no test");
                return;
            }
            try {
                System.out.println("get");
            } finally {
                lock.unlock();
            }
        }, "t1");

        // 主线程先lock
        lock.lock();
        System.out.println("get");
        t1.start();
        sleep(4);
        System.out.println("release");
        lock.unlock();
    }
}

打断:

打断是我自己的线程打断我自己不是别人打断我。

用简单的lock方法,就是死等的,不能打断。

-------------------------------------04---73----------------------------------------

可打断是被动的。

锁超时是尝试获取锁超时,之后直接返回不在阻塞队列里面阻塞了。

可以是带参数的也可以是不带参数的。

测试可超时:

package cn.itcast.test;

import lombok.extern.slf4j.Slf4j;

import java.sql.Time;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;

import static cn.itcast.n2.util.Sleeper.sleep;

@Slf4j(topic = "c.Test22")
public class Test22 {
    private static ReentrantLock lock = new ReentrantLock();
    public static void main(String[] args) {
        Thread t1 = new Thread(() -> {
            log.debug("尝试获得锁");
            try {
                if (! lock.tryLock(2, TimeUnit.SECONDS)) {
                    log.debug("获取不到锁");
                    return;
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
                log.debug("获取不到锁");
                return;
            }
            try {
                log.debug("获得到锁");
            } finally {
                lock.unlock();
            }
        }, "t1");

        lock.lock();
        log.debug("获得到锁");
        t1.start();
        sleep(4);
        log.debug("释放了锁");
        lock.unlock();
    }
}

tryLock也是可以被打断的。

--------------------------------------04-------74--------------------------------------------

锁的超时解决哲学家就餐问题。

哲学家就餐:这个就是把syn变为reentrantLock

-------------------------------------04--75---------------------------------------

公平锁和非公平锁。

默认是不公平的。

-----------------------------------04---76------------------------------------------

条件变量是重点的。

await被唤醒或者打断的话就进入到reentrantlock的等待队列里面的。

锁是一样的就是等待的屋子是不一样的,唤醒的屋子里的人也是不一样的。

代码:

package cn.itcast.test;

import lombok.extern.slf4j.Slf4j;

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

import static cn.itcast.n2.util.Sleeper.sleep;

@Slf4j(topic = "c.Test24")
public class Test24 {
    static final Object room = new Object();
    static boolean hasCigarette = false;
    static boolean hasTakeout = false;
    static ReentrantLock ROOM = new ReentrantLock();
    // 等待烟的休息室
    static Condition waitCigaretteSet = ROOM.newCondition();
    // 等外卖的休息室
    static Condition waitTakeoutSet = ROOM.newCondition();

    public static void main(String[] args) {


        new Thread(() -> {
            ROOM.lock();
            try {
                log.debug("有烟没?[{}]", hasCigarette);
                while (!hasCigarette) {
                    log.debug("没烟,先歇会!");
                    try {
                        waitCigaretteSet.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                log.debug("可以开始干活了");
            } finally {
                ROOM.unlock();
            }
        }, "小南").start();

        new Thread(() -> {
            ROOM.lock();
            try {
                log.debug("外卖送到没?[{}]", hasTakeout);
                while (!hasTakeout) {
                    log.debug("没外卖,先歇会!");
                    try {
                        waitTakeoutSet.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                log.debug("可以开始干活了");
            } finally {
                ROOM.unlock();
            }
        }, "小女").start();

        sleep(1);
        new Thread(() -> {
            ROOM.lock();
            try {
                hasTakeout = true;
                waitTakeoutSet.signal();
            } finally {
                ROOM.unlock();
            }
        }, "送外卖的").start();

        sleep(1);

        new Thread(() -> {
            ROOM.lock();
            try {
                hasCigarette = true;
                waitCigaretteSet.signal();
            } finally {
                ROOM.unlock();
            }
        }, "送烟的").start();
    }

}

----------------------------04------------78--79-----

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值