并发编程(三) Lock用法

1. lock():获取锁,如果锁不可用,则当前线程将被禁用以进行线程调度,并处于休眠状态,直到获取锁。
package com.zsx.demo.lock;

import lombok.extern.log4j.Log4j2;

import java.time.LocalDateTime;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

@Log4j2
public class LockMethodLock {

    private final Lock lock = new ReentrantLock();

    public void printLock() {
        try {
            lock.lock();
            log.info("Current thread {} get lock, enters the printLock method, enter current time : {}", Thread.currentThread().getName(), LocalDateTime.now());
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            log.info("Current thread {} unlock, exits the printLock method, exit current time : {}", Thread.currentThread().getName(), LocalDateTime.now());
            lock.unlock();
        }
    }

    public static void main(String[] args) {
        for (int i = 0; i < 5; i++) {
            LockMethodLock lockDemo = new LockMethodLock();
            new Thread(() -> {
                lockDemo.printLock();
            }, String.format("A-t%d", i)).start();
        }
    }
}
1.运行结果
18:16:36.694 [A-t1] INFO com.zsx.demo.lock.LockMethodLock - Current thread A-t1 get lock, enters the printLock method, enter current time : 2019-12-05T18:16:36.687915900
18:16:36.694 [A-t0] INFO com.zsx.demo.lock.LockMethodLock - Current thread A-t0 get lock, enters the printLock method, enter current time : 2019-12-05T18:16:36.687915900
18:16:36.694 [A-t4] INFO com.zsx.demo.lock.LockMethodLock - Current thread A-t4 get lock, enters the printLock method, enter current time : 2019-12-05T18:16:36.687915900
18:16:36.694 [A-t3] INFO com.zsx.demo.lock.LockMethodLock - Current thread A-t3 get lock, enters the printLock method, enter current time : 2019-12-05T18:16:36.687915900
18:16:36.694 [A-t2] INFO com.zsx.demo.lock.LockMethodLock - Current thread A-t2 get lock, enters the printLock method, enter current time : 2019-12-05T18:16:36.687915900
18:16:38.701 [A-t3] INFO com.zsx.demo.lock.LockMethodLock - Current thread A-t3 unlock, exits the printLock method, exit current time : 2019-12-05T18:16:38.701869900
18:16:38.701 [A-t1] INFO com.zsx.demo.lock.LockMethodLock - Current thread A-t1 unlock, exits the printLock method, exit current time : 2019-12-05T18:16:38.701869900
18:16:38.701 [A-t4] INFO com.zsx.demo.lock.LockMethodLock - Current thread A-t4 unlock, exits the printLock method, exit current time : 2019-12-05T18:16:38.701869900
18:16:38.701 [A-t2] INFO com.zsx.demo.lock.LockMethodLock - Current thread A-t2 unlock, exits the printLock method, exit current time : 2019-12-05T18:16:38.701869900
18:16:38.701 [A-t0] INFO com.zsx.demo.lock.LockMethodLock - Current thread A-t0 unlock, exits the printLock method, exit current time : 2019-12-05T18:16:38.701869900
2.tryLock():如果获取成功,则返回true,如果获取失败,则返回false
tryLock(long time, TimeUnit unit):如果一开始拿到锁或者在等待期间内拿到了锁,返回true,否则返回false
package com.zsx.demo.lock;

import lombok.extern.log4j.Log4j2;

import java.time.LocalDateTime;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

@Log4j2
public class LockMethodPrintTryLock {

    private final Lock lock = new ReentrantLock();

    public void printTryLock() {
        if (lock.tryLock()) {
            try {
                log.info("Current thread {} get lock, enters the printTryLock method, enter current time : {}", Thread.currentThread().getName(), LocalDateTime.now());
                TimeUnit.SECONDS.sleep(4);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                log.info("Current thread {} unlock, exits the printTryLock method, exit current time : {}", Thread.currentThread().getName(), LocalDateTime.now());
                lock.unlock();
            }
        } else {
            log.info("Failed to acquire lock on current thread {}, enters the printTryLock method, enter current time : {}", Thread.currentThread().getName(), LocalDateTime.now());
        }
    }

    public void printTryLockLong(long time) {
        try {
            if (lock.tryLock(time, TimeUnit.SECONDS)) {
                try {
                    log.info("Current thread {} get lock, enters the printTryLockLong method, enter current time : {}", Thread.currentThread().getName(), LocalDateTime.now());
                    TimeUnit.SECONDS.sleep(time);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    log.info("Current thread {} unlock, exits the printTryLockLong method, exit current time : {}", Thread.currentThread().getName(), LocalDateTime.now());
                    lock.unlock();
                }
            } else {
                log.info("Failed to acquire lock on current thread {}, enters the printTryLock method, enter current time : {}", Thread.currentThread().getName(), LocalDateTime.now());
            }
        } catch (InterruptedException e) {
            log.info("The current thread {} is interrupted", Thread.currentThread().getName());
        }
    }

    public static void main(String[] args) {
        LockMethodPrintTryLock lock = new LockMethodPrintTryLock();
        new Thread(() -> {
            lock.printTryLock();
        }, "t1").start();
        try {
            // 让t1先执行
            TimeUnit.MILLISECONDS.sleep(300);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        new Thread(() -> {
            // 由于t1中间停顿4秒, t2在规定时间内拿不到锁
            lock.printTryLockLong(2);
        }, "t2").start();

        try {
            // 确保t1、t2执行完,释放锁,不影响后续操作
            TimeUnit.SECONDS.sleep(6);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        new Thread(() -> {
            lock.printTryLockLong(5);
        }, "t3").start();
        try {
            // 让t3先执行
            TimeUnit.MILLISECONDS.sleep(300);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        new Thread(() -> {
            // t3没有释放锁,t4拿不到锁
            lock.printTryLock();
        }, "t4").start();
    }
}
2.运行结果
16:52:35.073 [t1] INFO com.zsx.demo.lock.LockMethodPrintTryLock - Current thread t1 get lock, enters the printTryLock method, enter current time : 2019-12-05T16:52:35.067740200
16:52:37.362 [t2] INFO com.zsx.demo.lock.LockMethodPrintTryLock - Failed to acquire lock on current thread t2, enters the printTryLock method, enter current time : 2019-12-05T16:52:37.362847500
16:52:39.077 [t1] INFO com.zsx.demo.lock.LockMethodPrintTryLock - Current thread t1 unlock, exits the printTryLock method, exit current time : 2019-12-05T16:52:39.077296900
16:52:41.364 [t3] INFO com.zsx.demo.lock.LockMethodPrintTryLock - Current thread t3 get lock, enters the printTryLockLong method, enter current time : 2019-12-05T16:52:41.364905500
16:52:41.665 [t4] INFO com.zsx.demo.lock.LockMethodPrintTryLock - Failed to acquire lock on current thread t4, enters the printTryLock method, enter current time : 2019-12-05T16:52:41.665123700
16:52:46.365 [t3] INFO com.zsx.demo.lock.LockMethodPrintTryLock - Current thread t3 unlock, exits the printTryLockLong method, exit current time : 2019-12-05T16:52:46.365824600
3.lockInterruptibly()方法:当通过这个方法去获取锁时,如果线程正在等待获取锁,则这个线程能够响应中断,即中断线程的等待状态
package com.zsx.demo.lock;

import lombok.extern.log4j.Log4j2;

import java.time.LocalDateTime;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

@Log4j2
public class LockMethodLockInterruptibly {

    private final Lock lock = new ReentrantLock();

    public void printLockInterruptibly() throws InterruptedException {
        lock.lockInterruptibly();
        try {
            log.info("Current thread {} get lock, enters the printLockInterruptibly method, enter current time : {}", Thread.currentThread().getName(), LocalDateTime.now());
            while(true) {

            }
        } finally {
            log.info("Current thread {} unlock,  exits the printLockInterruptibly method, exit current time : {}", Thread.currentThread().getName(), LocalDateTime.now());
            lock.unlock();
        }
    }

    public static void main(String[] args) {
        LockMethodLockInterruptibly lock = new LockMethodLockInterruptibly();
        Thread t1 = new Thread(() -> {
            try {
                lock.printLockInterruptibly();
            } catch (InterruptedException e) {
                log.info("The current thread {} is interrupted", Thread.currentThread().getName());
            }
        }, "t1");
        // t1获得锁
        t1.start();
        try {
            // 为了保证t1先行t2运行,睡眠2秒
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        Thread t2 = new Thread(() -> {
            try {
                lock.printLockInterruptibly();
            } catch (InterruptedException e) {
                log.info("The current thread {} is interrupted", Thread.currentThread().getName());
            }
        }, "t2");
        // t2启动,尝试获取锁,由于t1一直持有该锁,t2进入等待状态
        t2.start();
        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        // 由于t1正在运行,无法中断
        t1.interrupt();
        // 等待2秒后中断t2
        t2.interrupt();
    }
}

3.运行结果

16:24:23.819 [t1] INFO com.zsx.demo.lock.LockMethodLockInterruptibly - Current thread t1 get lock, enters the printLockInterruptibly method, enter current time : 2019-12-05T16:24:23.814503400
16:24:27.810 [t2] INFO com.zsx.demo.lock.LockMethodLockInterruptibly - The current thread t2 is interrupted

4. newCondition():.通过Condition能够更加精准地控制多线程的休眠与唤醒。

package com.zsx.demo.lock;

import lombok.extern.log4j.Log4j2;

import java.time.LocalDateTime;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

@Log4j2
public class LockMethodNewCondition {

    private final Lock lock = new ReentrantLock();
    private volatile static int i = 1;

    public final Condition conditionA = lock.newCondition();
    public final Condition conditionB = lock.newCondition();
    public final Condition conditionC = lock.newCondition();

    public void printNewCondition(Condition awaitCondition, Condition signalCondition) {
        try {
            lock.lock();
            log.info("Current thread {} get lock, enters the printNewCondition method, enter current time : {}", Thread.currentThread().getName(), LocalDateTime.now());
            TimeUnit.SECONDS.sleep(2);
            if (i < 3) {
                log.info("i: {}", i);
                i++;
                // 让线程进入等待状态
                awaitCondition.await();
                // 唤醒指定的线程
                signalCondition.signal();
            } else {
                signalCondition.signalAll();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            log.info("Current thread {} unlock, exits the printNewCondition method, exit current time : {}", Thread.currentThread().getName(), LocalDateTime.now());
            lock.unlock();
        }
    }

    public static void main(String[] args) {
        LockMethodNewCondition lock1 = new LockMethodNewCondition();
        new Thread(() -> {
            lock1.printNewCondition(lock1.conditionA, lock1.conditionB);
        }, "A").start();
        new Thread(() -> {
            lock1.printNewCondition(lock1.conditionB, lock1.conditionC);
        }, "B").start();
        new Thread(() -> {
            lock1.printNewCondition(lock1.conditionC, lock1.conditionA);
        }, "C").start();
    }
}

4.运行结果

20:15:54.112 [A] INFO com.zsx.demo.lock.LockMethodNewCondition - Current thread A get lock, enters the printNewCondition method, enter current time : 2019-12-05T20:15:54.097225200
20:15:56.128 [A] INFO com.zsx.demo.lock.LockMethodNewCondition - i: 1
20:15:56.128 [B] INFO com.zsx.demo.lock.LockMethodNewCondition - Current thread B get lock, enters the printNewCondition method, enter current time : 2019-12-05T20:15:56.128307900
20:15:58.143 [B] INFO com.zsx.demo.lock.LockMethodNewCondition - i: 2
20:15:58.143 [C] INFO com.zsx.demo.lock.LockMethodNewCondition - Current thread C get lock, enters the printNewCondition method, enter current time : 2019-12-05T20:15:58.143450800
20:16:00.158 [C] INFO com.zsx.demo.lock.LockMethodNewCondition - Current thread C unlock, exits the printNewCondition method, exit current time : 2019-12-05T20:16:00.158601600
20:16:00.158 [A] INFO com.zsx.demo.lock.LockMethodNewCondition - Current thread A unlock, exits the printNewCondition method, exit current time : 2019-12-05T20:16:00.158601600
20:16:00.158 [B] INFO com.zsx.demo.lock.LockMethodNewCondition - Current thread B unlock, exits the printNewCondition method, exit current time : 2019-12-05T20:16:00.158601600
发布了129 篇原创文章 · 获赞 14 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/zsx18273117003/article/details/103407558
今日推荐