• J.U.C并发编程包详解 (1) Lock接口


    一、Lock锁接口

      定义Java中Java.Util.concurrent 中锁 Lock 的基本接口方法

    二、Lock 接口方法

    Lock 接口有以下几个方法

    public interface Lock {
    
        void lock();
    
        void lockInterruptibly() throws InterruptedException;
    
        boolean tryLock();
    
        boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
    
        void unlock();
    
        Condition newCondition();
    
    }
    

      

    lock() 是一直等到获取锁

    void lock();
    

     

    tryLock() 是尝试获取锁

    boolean tryLock();
    

      

    tryLock(Long time, TimeUnit time) 设置尝试在某个时间内获取锁,过了这个时间就不尝试获取了

    boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
    

    lockInterruptibly 中止锁  

    void lockInterruptibly() throws InterruptedException;
    

    unlock( ) 解锁

    unlock();
    

      

    newCondition  稍后解释

    Condition newCondition();
    

      

    三、lock 使用

      Lock的使用,通过实现Lock接口的 ReentranLock 类来实现;

    3.1、lock()  

    import org.apache.tomcat.jni.Time;
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    
    public class LockDemo {
    
        static Lock lock = new ReentrantLock();
    
        public static void main(String[] args) throws Exception{
    
            lock.lock();
    
            Thread th = new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println("========= Try to get lock : " + System.currentTimeMillis());
    // lock 会一直等到线程可以拿到锁为止再运行 lock.lock(); System.out.println("========= Get lock : " + System.currentTimeMillis()); } }); System.out.println("========= Begin : " + System.currentTimeMillis()); th.start(); Thread.sleep(2000); System.out.println("========= After sleep: " + System.currentTimeMillis()); lock.unlock(); System.out.println("========= End : " + System.currentTimeMillis()); } }

    打印

    ========= Begin :           1596676916634
    ========= Try to get lock : 1596676916636
    ========= After sleep:      1596676918636
    ========= Get lock :        1596676918637
    ========= End :             1596676918637

    代码演示图

     说明:

    (1)主线程 A 先获取到锁;

    (2)启动另外一个线程 B;

    (3)线程 B 尝试获取 锁,获取不到,进入锁池, 等待获取锁,运行跳回主线程A;

      (4)线程 A 进入休眠 2 秒;

    (5)线程 A 休眠完,解开锁,运行并跳回线程 B;

      (6)  线程 B 获取锁;

    (7)程序结束

    3.2、tryLock()

    public class LockDemo {
    
        static Lock lock = new ReentrantLock();
    
        public static void main(String[] args) throws Exception{
    
            lock.lock();
    
            Thread th = new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println("========= Try to get lock : " + System.currentTimeMillis());
                    boolean get = lock.tryLock();
    //这里将显示失败, 因为主线程没有释放锁,所以这个线程获取不到 System.out.println("========= Get lock : " + get ); System.out.println("======== Get lock Time : " + System.currentTimeMillis()); } }); System.out.println("========= Begin : " + System.currentTimeMillis()); th.start(); Thread.sleep(2000); System.out.println("========= After sleep: " + System.currentTimeMillis()); lock.unlock(); System.out.println("========= End : " + System.currentTimeMillis()); } }

    打印

    ========= Begin :           1596678142300
    ========= Try to get lock : 1596678142300
    ========= Get lock :        false
    ======== Get lock Time :    1596678142301
    ========= After sleep:      1596678144300
    ========= End :             1596678144300

    可以看到,由于这个方法,线程没有进入锁池等待获取锁,只要没有获取到锁就不等待了。

    3.3、tryLock(Long time, TimeUnit time) 

    public class LockDemo {
    
        static Lock lock = new ReentrantLock();
    
        public static void main(String[] args) throws Exception{
    
            lock.lock();
    
            Thread th = new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println("========= Try to get lock : " + System.currentTimeMillis());
                    boolean get = false;
                   // 线程在这里等 3秒, 获取到锁 
    try { get = lock.tryLock(3000, TimeUnit.SECONDS); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("========= Get lock : " + get ); System.out.println("========= Get lock Time : " + System.currentTimeMillis()); } }); System.out.println("========= Begin : " + System.currentTimeMillis()); th.start(); Thread.sleep(2000); System.out.println("========= After sleep: " + System.currentTimeMillis()); lock.unlock(); System.out.println("========= End : " + System.currentTimeMillis()); } }

    打印

    ========= Begin :           1596678402148
    ========= Try to get lock : 1596678402161
    ========= After sleep:      1596678404148
    ========= End :             1596678404148
    ========= Get lock :        true
    ========= Get lock Time :    1596678404148

     3.4 lockInterruptibly( )

          线程B 等到 线程B调用 interrupt() 方法就不等了

    public class InterrupteLockDemo {
    
        static Lock lock = new ReentrantLock();
    
        public static void main(String[] args) throws Exception{
    
            lock.lock();
    
            Thread th = new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println("========= Try to get lock : " + System.currentTimeMillis());
    
                    try {
    /*等待,获取锁,直到线程调用 interrupt(), 就不等了*/ lock.lockInterruptibly(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("========= Get lock Time : " + System.currentTimeMillis()); } }); System.out.println("========= Begin : " + System.currentTimeMillis()); th.start(); Thread.sleep(2000); System.out.println("========= After sleep: " + System.currentTimeMillis()); th.interrupt(); Thread.sleep(2000); System.out.println("========= End : " + System.currentTimeMillis()); } }

    打印

    ========= Begin :           1596683400461
    ========= Try to get lock : 1596683400462
    ========= After sleep:      1596683402477
    ========= Get lock Time :   1596683402479
    java.lang.InterruptedException
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireInterruptibly(AbstractQueuedSynchronizer.java:898)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireInterruptibly(AbstractQueuedSynchronizer.java:1222)
        at java.util.concurrent.locks.ReentrantLock.lockInterruptibly(ReentrantLock.java:335)
        at com.jm.lock.InterrupteLockDemo$1.run(InterrupteLockDemo.java:21)
        at java.lang.Thread.run(Thread.java:748)
    ========= End :             1596683404478

    3.5 new Condition

    public class newCondition {
    
        static Lock lock = new ReentrantLock();
        static private Condition condition = lock.newCondition();
    
        public static void main(String[] args) throws Exception{
    
            Thread th = new Thread(new Runnable() {
                @Override
                public void run() {
    
                    lock.lock();
                    try {
                        System.out.println("当前线程 获得锁 :  " + System.currentTimeMillis());
                        condition.await();//挂起线程
                        System.out.println("当前线程 开始执行: " + System.currentTimeMillis());
    
                    } catch (InterruptedException e) {
                        lock.unlock();
                        e.printStackTrace();
                    }
    
                    System.out.println("========= Get lock Time :    " + System.currentTimeMillis());
    
    
                }
            });
    
            System.out.println("========= Begin :           " + System.currentTimeMillis());
            th.start();
            Thread.sleep(2000);
            System.out.println("========= After sleep:      " + System.currentTimeMillis());
            lock.lock();
            condition.signal();
            lock.unlock();
            System.out.println("========= End :             " + System.currentTimeMillis());
    
        }
    }
    

      

    
    
    
  • 相关阅读:
    python报以下错误:TypeError: 'int' object is not subscriptable
    C# Func与Action
    C#调用C++的DLL 尝试写入受保护的内存
    C#调用C++的dll EntryPointNotFoundException
    C# 拖拽事件
    C#操作Access数据库中遇到的问题(待续)
    Winform 中写代码布局中遇到的控件遮盖问题
    thinkphp6执行流程(一)
    xdebug调试过程中apache500超时
    禁用phpcookie以后如何使用Session
  • 原文地址:https://www.cnblogs.com/Jomini/p/13443683.html
Copyright © 2020-2023  润新知