ReentrantLock学习

ReentrantLock学习

ReentrantLock

ReentrantLock功能

  • ReentrantLock和synchronized一样是可重入的

    • 可重入即当线程拥有了锁时,当该线程再次请求锁资源的时候,线程是可以再次成功获得的。

    • static ReentrantLock lock = new ReentrantLock();public static void main(String[] args) {    new Thread(() ->{        lock.lock();        try{            log.debug("获得了锁,再次请求锁");            lock.lock();            try{                log.debug("再次获得了锁");            }finally {                log.debug("释放了锁");                lock.unlock();            }        }finally {            log.debug("释放了锁");            lock.unlock();        }    },"t1").start();    }
  • ReentrantLock是可打断的

    • 即请求锁资源的时候,当请求不到锁资源的时候,可以被interrupt方法打断。

    • static ReentrantLock lock = new ReentrantLock();public static void main(String[] args) {    Thread t1 = new Thread(() -> {        try {            // 如果当lock请求锁资源的同时被其他其他线程调用了interrupt方法            // 就会进入异常状态            lock.lockInterruptibly();        } catch (InterruptedException e) {            e.printStackTrace();            log.debug("请求锁被打断");            return; // 当请求锁被打断后没有获得锁,不应该在进入下面的语句        }        try {            log.debug("获得到了锁资源");        } finally {            lock.unlock();        }    }, "t1");    lock.lock();    t1.start();    try {        Thread.sleep(1000);    } catch (InterruptedException e) {        e.printStackTrace();    }    t1.interrupt();}
  • ReentrantLock可以锁超时

    • synchronized请求锁会一直地等待锁资源,而ReentrantLock请求锁不会无限制的进行下去,使用tryLock()方法,可以在一次请求锁资源或请求一段时间的锁资源后结束请求锁。

    •     static ReentrantLock lock = new ReentrantLock();    public static void main(String[] args) throws InterruptedException {        Thread t1 = new Thread(() -> {            log.debug("开始运行了");            // 该情况下只会请求一次锁资源,请求到锁资源返回true,否则返回false            // 加上时间限制的trylock是一样的。            try {                if (lock.tryLock(2, TimeUnit.SECONDS)) {                    try {                        log.debug("请求到了锁资源");                    } finally {                        lock.unlock();                    }                } else {                    log.debug("没请求到锁资源");                }            } catch (InterruptedException e) {                e.printStackTrace();            }        }, "t1");        lock.lock();        log.debug("上锁了");        t1.start();        Thread.sleep(1000);        log.debug("解锁了");        lock.unlock();    }
  • 当一些线程一直无法获得锁资源时,使用公平锁就可以时获得锁变成先进先获得。

    • static ReentrantLock lock = new ReentrantLock(true);
  • 条件变量,即ReentrantLock支持多条件的进入不同的WaitSet进行等待,synchronized就只有一个WaitSet队列。

    • 当出现需要不同条件进入等待就可以使用该条件变量。

    • static ReentrantLock lock = new ReentrantLock();static Condition waitCondition1Set = lock.newCondition();// 然后调用condition的await方法即可进入等待状态。

设计模式---顺序执行

保证线程执行的一致性,因为这里是同一个锁对象所以不能用join

wait-notify

@Slf4jpublic class Test5 {    static boolean already = false;    public static void main(String[] args) {        final Object o = new Object();        Thread t1 = new Thread(() -> {            synchronized (o){                while (!already){                    try {                        o.wait();                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                }                log.debug("1");            }        }, "t1");        Thread t2 = new Thread(() -> {            synchronized (o){                log.debug("2");                already = true;                o.notify();            }        }, "t2");        t1.start();        t2.start();    }}

park-unpark

@Slf4jpublic class Test6 {    public static void main(String[] args) throws InterruptedException {        Thread t1 = new Thread(() -> {            LockSupport.park();            log.debug("1");        }, "t1");        Thread t2 = new Thread(() -> {            LockSupport.park();            log.debug("2");            LockSupport.unpark(t1);        }, "t2");        t1.start();        t2.start();        Thread.sleep(2000);        LockSupport.unpark(t2);    }}

设计模式---交替输出

三个线程交替输出

wait-notify

public class Test7 {    public static void main(String[] args) {        PrintObject object = new PrintObject(5,2);        Thread t1 = new Thread(() -> {            object.print(2,1);        }, "t1");        Thread t2 = new Thread(() -> {            object.print(3,2);        }, "t2");        Thread t3 = new Thread(() -> {            object.print(1,3);        }, "t3");        t1.start();        t2.start();        t3.start();    }}class PrintObject{    private int loopNum;    private int flag;    public PrintObject(int loopNum,int flag) {        this.loopNum = loopNum;        this.flag = flag;    }    public synchronized void print(int next,int now){        for(int i = 0;i < loopNum;i++){            while (flag != now){                try {                    wait();                } catch (InterruptedException e) {                    e.printStackTrace();                }            }            System.out.println(now);            flag = next;            notifyAll();        }    }}

await-signal

class PrintObject{    private ReentrantLock lock = new ReentrantLock();    private Condition condition = lock.newCondition();    private int loopNum;    private int flag;    public PrintObject(int loopNum,int flag) {        this.loopNum = loopNum;        this.flag = flag;    }    public void print(int next,int now){        lock.lock();        try{            for(int i = 0;i < loopNum;i++){                while (flag != now){                    try {                        condition.await();                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                }                System.out.println(flag);                flag = next;                condition.signalAll();            }        }finally {            lock.unlock();        }    }}

park-unpark

@Slf4jpublic class Test8 {    static Thread t1;    static Thread t2;    static Thread t3;    public static void main(String[] args) throws InterruptedException {        t1 = new Thread(() -> {            LockSupport.park();            log.debug("1");            LockSupport.unpark(t2);        }, "t1");        t2 = new Thread(() -> {            LockSupport.park();            log.debug("2");            LockSupport.unpark(t3);        }, "t2");        t3 = new Thread(() -> {            LockSupport.park();            log.debug("3");            LockSupport.unpark(t1);        }, "t3");        t1.start();        t2.start();        t3.start();        Thread.sleep(1000);        LockSupport.unpark(t1);    }}
免责声明:本网信息来自于互联网,目的在于传递更多信息,并不代表本网赞同其观点。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,并请自行核实相关内容。本站不承担此类作品侵权行为的直接责任及连带责任。如若本网有任何内容侵犯您的权益,请及时联系我们,本站将会在24小时内处理完毕。
相关文章
返回顶部