笔记

万物寻其根,通其堵,便能解其困。
  博客园  :: 新随笔  :: 管理

spring boot 锁处理

Posted on 2024-05-29 15:26  草妖  阅读(10)  评论(0)    收藏  举报
详情请参照,本文仅作笔记记录:阿里二面:Java中锁的分类有哪些?你能说全吗? - 码农Academy - 博客园 (cnblogs.com)

ReentrantLock:可重入锁,继承自Lock接口,支持可中断锁、公平锁和非公平锁的选择。可重入意味着同一个线程可以多次获取同一线程持有的锁。

ReentrantReadWriteLock:读写锁,提供了两个锁,一个是读锁,允许多个线程同时读取;另一个是写锁,同一时间内只允许一个线程写入,写锁会排斥所有读锁和写锁。

StampedLock:带版本戳的锁,提供了乐观读、悲观读写模式,适合于读多写少的场景,可以提升系统性能。

 


可重入锁:ReentrantLock
注:
中断锁(lockInterruptibly)、公平锁(new ReentrantLock(true))和非公平锁(new ReentrantLock(false)),默认非公平锁
     /**
         * ReentrantLock 可重入锁
         * *.lock() 堵塞执行同步处理功能;
         * *.tryLock() 如果锁在给定的等待时间内空闲并且当前线程未被中断,则获取锁。
         */
        Lock lock1 = new ReentrantLock();  // 测试lock
        Lock lock2 = new ReentrantLock();  // 测试tryLock
        Runnable tempRunnable1= () -> {
            try {
                lock1.lock();
                System.out.println(Thread.currentThread().getName()+"开始执行:"+DateTime.now().toString("yyyy-MM-dd HH:mm:ss"));
                Thread.sleep(5000);
                System.out.println(Thread.currentThread().getName()+"结束执行:"+DateTime.now().toString("yyyy-MM-dd HH:mm:ss"));
                lock1.unlock();
            } catch (Exception err) {
                System.out.println(Thread.currentThread().getName()+",执行Runnable异常:"+err.getMessage());
            }
        };
        Runnable tempRunnable2= () -> {
            try {
                lock1.lock();
                System.out.println(Thread.currentThread().getName()+"开始执行:"+DateTime.now().toString("yyyy-MM-dd HH:mm:ss"));
                Thread.sleep(2000);
                System.out.println(Thread.currentThread().getName()+"结束执行:"+DateTime.now().toString("yyyy-MM-dd HH:mm:ss"));
                lock1.unlock();
            } catch (Exception err) {
                System.out.println(Thread.currentThread().getName()+",执行Runnable异常:"+err.getMessage());
            }
        };
        // lock2.tryLock();直接获取锁。
        // lock2.tryLock(50,TimeUnit.MILLISECONDS);  如果锁在50毫秒时间内空闲并且当前线程未被中断,则获取(限时)锁。
        // 注:这种方式不会堵塞线程,会存在并列执行的情况,例如下面的情况:
        Runnable tempRunnable3= () -> {
            try {
                //lock2.tryLock();
                lock2.tryLock(1,TimeUnit.SECONDS);
                System.out.println(Thread.currentThread().getName()+"开始执行:"+DateTime.now().toString("yyyy-MM-dd HH:mm:ss"));
                Thread.sleep(5000);
                System.out.println(Thread.currentThread().getName()+"结束执行:"+DateTime.now().toString("yyyy-MM-dd HH:mm:ss"));
                lock2.unlock();
            } catch (Exception err) {
                System.out.println(Thread.currentThread().getName()+",执行Runnable异常:"+err.getMessage());
            }
        };
        Runnable tempRunnable4= () -> {
            try {
                //lock2.tryLock();
                lock2.tryLock(1,TimeUnit.SECONDS);
                System.out.println(Thread.currentThread().getName()+"开始执行:"+DateTime.now().toString("yyyy-MM-dd HH:mm:ss"));
                Thread.sleep(2000);
                System.out.println(Thread.currentThread().getName()+"结束执行:"+DateTime.now().toString("yyyy-MM-dd HH:mm:ss"));
                lock2.unlock();
            } catch (Exception err) {
                System.out.println(Thread.currentThread().getName()+",执行Runnable异常:"+err.getMessage());
            }
        };
        Thread tempThread1=new Thread(tempRunnable1,"tempThread1");
        Thread tempThread2=new Thread(tempRunnable2,"tempThread2");
        Thread tempThread3=new Thread(tempRunnable3,"tempThread3");
        Thread tempThread4=new Thread(tempRunnable4,"tempThread4");
        tempThread1.start();
        tempThread2.start();
        tempThread3.start();
        tempThread4.start();
        /* 输出:
            tempThread1开始执行:2024-05-29 17:02:24
            tempThread4开始执行:2024-05-29 17:02:24
            tempThread3开始执行:2024-05-29 17:02:25
            tempThread4结束执行:2024-05-29 17:02:26
            tempThread1结束执行:2024-05-29 17:02:29
            tempThread2开始执行:2024-05-29 17:02:29
            tempThread3结束执行:2024-05-29 17:02:30
            tempThread3,执行Runnable异常:null
            tempThread2结束执行:2024-05-29 17:02:31
         * */
中断锁:lockInterruptibly
        /**
         * lockInterruptibly可以将立即抛出InterruptedException,并清除中断状态,然后从异常处继续执行,通常是通过返回,释放锁并退出。
         * 这样可以避免线程持有锁而其它线程永远等待锁释放的情况。
         * **/
        Lock lock= new ReentrantLock();
        Runnable tempRunnable1= () -> {
            try {
                lock.lock();
                System.out.println(Thread.currentThread().getName()+"开始");
                Thread.sleep(5000);
            } catch (Exception err) {
                System.out.println(Thread.currentThread().getName()+",执行Runnable异常:"+err.getMessage());
            }finally {
                System.out.println(Thread.currentThread().getName()+"结束");
                lock.unlock();
            }
        };
        Runnable tempRunnable2= () -> {
            try {
                System.out.println(Thread.currentThread().getName()+"开始1");
                lock.lockInterruptibly();
                System.out.println(Thread.currentThread().getName()+"开始2");
                Thread.sleep(5000);
                lock.unlock();  // 无需在finally中释放,如果存在interrupt异常,lockInterruptibly会执行回收
            } catch (Exception err) {
                System.out.println(Thread.currentThread().getName()+",执行Runnable异常:"+err.getMessage());
            }finally {
                System.out.println(Thread.currentThread().getName()+"结束");
            }
        };
        Runnable tempRunnable3= () -> {
            try {
                lock.lock();
                System.out.println(Thread.currentThread().getName()+"开始");
                Thread.sleep(6000);
            } catch (Exception err) {
                System.out.println(Thread.currentThread().getName()+",执行Runnable异常:"+err.getMessage());
            }finally {
                System.out.println(Thread.currentThread().getName()+"结束");
                lock.unlock();
            }
        };
        Thread tempThread1=new Thread(tempRunnable1,"tempThread1");
        Thread tempThread2=new Thread(tempRunnable2,"tempThread2");
        Thread tempThread3=new Thread(tempRunnable3,"tempThread3");
        tempThread1.start();
        tempThread2.start();
        tempThread3.start();
        Thread.sleep(1000);
        tempThread2.interrupt();

 输出:
tempThread1开始
tempThread2开始1
tempThread2,执行Runnable异常:null
tempThread2结束
tempThread1结束
tempThread3开始
tempThread3结束


读写锁:ReentrantReadWriteLock
     ReentrantReadWriteLock lock=new ReentrantReadWriteLock();
        int[] tempAAAA=new int[]{0};
        Runnable tempRunnable1= () -> {
            try {
                for(int i=0;i<50;i++){
                    lock.writeLock().lock();  // 写锁
                    System.out.println(Thread.currentThread().getName()+"开始执行写锁:"+DateTime.now().toString("yyyy-MM-dd HH:mm:ss"));
                    tempAAAA[0]+=1;
                    Thread.sleep(1000);
                    System.out.println(Thread.currentThread().getName()+"释放执行写锁:"+DateTime.now().toString("yyyy-MM-dd HH:mm:ss"));
                    lock.writeLock().unlock();  // 释放写锁
                }
            } catch (Exception err) {
                System.out.println(Thread.currentThread().getName()+",执行Runnable异常:"+err.getMessage());
            }
        };
        Runnable tempRunnable2= () -> {
            try {
                for(int i=0;i<50;i++){
                    lock.writeLock().lock();  // 写锁
                    System.out.println(Thread.currentThread().getName()+"开始执行写锁:"+DateTime.now().toString("yyyy-MM-dd HH:mm:ss"));
                    tempAAAA[0]+=1;
                    Thread.sleep(1200);
                    System.out.println(Thread.currentThread().getName()+"释放执行写锁:"+DateTime.now().toString("yyyy-MM-dd HH:mm:ss"));
                    lock.writeLock().unlock();  // 释放写锁
                }
            } catch (Exception err) {
                System.out.println(Thread.currentThread().getName()+",执行Runnable异常:"+err.getMessage());
            }
        };
        Runnable tempRunnable3= () -> {
            try {
                int i=1000000;
                while (i>0){
                    lock.readLock().lock();  // 读锁
                    System.out.println(Thread.currentThread().getName()+"开始执行读锁:"+DateTime.now().toString("yyyy-MM-dd HH:mm:ss"));
                    System.out.println(Thread.currentThread().getName()+":"+tempAAAA[0]);
                    Thread.sleep(200);
                    System.out.println(Thread.currentThread().getName()+"释放执行读锁:"+DateTime.now().toString("yyyy-MM-dd HH:mm:ss"));
                    lock.readLock().unlock();  // 释放读锁
                    i--;
                }
            } catch (Exception err) {
                System.out.println(Thread.currentThread().getName()+",执行Runnable异常:"+err.getMessage());
            }
        };
        Runnable tempRunnable4= () -> {
            try {
                int i=1000000;
                while (i>0){
                    lock.readLock().lock();  // 读锁
                    System.out.println(Thread.currentThread().getName()+"开始执行读锁:"+DateTime.now().toString("yyyy-MM-dd HH:mm:ss"));
                    System.out.println(Thread.currentThread().getName()+":"+tempAAAA[0]);
                    Thread.sleep(300);
                    System.out.println(Thread.currentThread().getName()+"释放执行读锁:"+DateTime.now().toString("yyyy-MM-dd HH:mm:ss"));
                    lock.readLock().unlock();  // 释放读锁
                    i--;
                }
            } catch (Exception err) {
                System.out.println(Thread.currentThread().getName()+",执行Runnable异常:"+err.getMessage());
            }
        };

        Runnable tempRunnable5= () -> {
            try {
                int i=1000000;
                while (i>0){
                    lock.readLock().lock();  // 读锁
                    System.out.println(Thread.currentThread().getName()+"开始执行读锁:"+DateTime.now().toString("yyyy-MM-dd HH:mm:ss"));
                    System.out.println(Thread.currentThread().getName()+":"+tempAAAA[0]);
                    Thread.sleep(400);
                    System.out.println(Thread.currentThread().getName()+"释放执行读锁:"+DateTime.now().toString("yyyy-MM-dd HH:mm:ss"));
                    lock.readLock().unlock();  // 释放读锁
                    i--;
                }
            } catch (Exception err) {
                System.out.println(Thread.currentThread().getName()+",执行Runnable异常:"+err.getMessage());
            }
        };
        Thread tempThread5=new Thread(tempRunnable5,"tempThread5");
        Thread tempThread4=new Thread(tempRunnable4,"tempThread4");
        Thread tempThread3=new Thread(tempRunnable3,"tempThread3");
        Thread tempThread2=new Thread(tempRunnable2,"tempThread2");
        Thread tempThread1=new Thread(tempRunnable1,"tempThread1");
        System.out.println("开始....");
        tempThread3.start();
        tempThread4.start();
        tempThread5.start();
        tempThread1.start();
        tempThread2.start();
        System.out.println("结束....");

输出:

开始....
结束....
tempThread3开始执行读锁:2024-05-29 15:46:03
tempThread5开始执行读锁:2024-05-29 15:46:03
tempThread4开始执行读锁:2024-05-29 15:46:03
tempThread4:0
tempThread5:0
tempThread3:0
tempThread3释放执行读锁:2024-05-29 15:46:03
tempThread4释放执行读锁:2024-05-29 15:46:03
tempThread5释放执行读锁:2024-05-29 15:46:03
tempThread1开始执行写锁:2024-05-29 15:46:03
tempThread1释放执行写锁:2024-05-29 15:46:04
tempThread1开始执行写锁:2024-05-29 15:46:04
tempThread1释放执行写锁:2024-05-29 15:46:05
...
tempThread1开始执行写锁:2024-05-29 15:46:14 tempThread1释放执行写锁:2024-05-29 15:46:15 tempThread1开始执行写锁:2024-05-29 15:46:15 tempThread1释放执行写锁:2024-05-29 15:46:16 tempThread2开始执行写锁:2024-05-29 15:46:16 tempThread2释放执行写锁:2024-05-29 15:46:17 tempThread2开始执行写锁:2024-05-29 15:46:17 tempThread2释放执行写锁:2024-05-29 15:46:19 tempThread2开始执行写锁:2024-05-29 15:46:19 tempThread2释放执行写锁:2024-05-29 15:46:20
...
tempThread2开始执行写锁:2024-05-29 15:46:23 tempThread2释放执行写锁:2024-05-29 15:46:25 tempThread2开始执行写锁:2024-05-29 15:46:25 tempThread2释放执行写锁:2024-05-29 15:46:26 tempThread3开始执行读锁:2024-05-29 15:46:26 tempThread3:21 tempThread4开始执行读锁:2024-05-29 15:46:26 tempThread4:21 tempThread5开始执行读锁:2024-05-29 15:46:26 tempThread5:21 tempThread3释放执行读锁:2024-05-29 15:46:26 tempThread4释放执行读锁:2024-05-29 15:46:26 tempThread5释放执行读锁:2024-05-29 15:46:26 tempThread1开始执行写锁:2024-05-29 15:46:26 tempThread1释放执行写锁:2024-05-29 15:46:27 tempThread1开始执行写锁:2024-05-29 15:46:27 tempThread1释放执行写锁:2024-05-29 15:46:28 tempThread1开始执行写锁:2024-05-29 15:46:28 tempThread1释放执行写锁:2024-05-29 15:46:29 tempThread1开始执行写锁:2024-05-29 15:46:29 已与地址为 ''127.0.0.1:1758',传输: '套接字'' 的目标虚拟机断开连接 进程已结束,退出代码为 -1

 

StampedLock
        // 创建锁
        StampedLock tempSLock=new StampedLock();
        // 写锁(排它锁、不可重入锁、独占锁)
        long stamp=tempSLock.writeLock();
        // 释放写锁
        tempSLock.unlockWrite(stamp);
        // 读锁(读写互斥,读读不互斥)
        stamp=tempSLock.readLock();
        // 释放读锁
        tempSLock.unlockRead(stamp);
        // 乐观读锁(非堵塞,允许一个写锁同时存在)
        // 注:因为非堵塞,故无法保证数据的一致性
        stamp=tempSLock.tryOptimisticRead();
        // 验证锁
        if(tempSLock.validate(stamp)){
            // 验证锁是否发生过变化/修改
            System.out.println("锁正常未修改...");
        }else {
            System.out.println("锁已经发生变化...");
        }
        // 进行锁转换处理
        tempSLock.tryConvertToReadLock(stamp);

读锁测试:readLock

 

        int[] tempAAA=new int[]{0,0};
        StampedLock tempSLock=new StampedLock();
        Runnable tempWriteRunnable1= () -> {
            long tempStamp=tempSLock.writeLock();
            tempAAA[1]+=1;
            tempSLock.unlockWrite(tempStamp);
            try {
                for(int i=0;i<50;i++){
                    tempStamp=tempSLock.writeLock();
                    System.out.println(Thread.currentThread().getName()+" 开始 写锁:"+DateTime.now().toString("yyyy-MM-dd HH:mm:ss"));
                    tempAAA[0]+=1;
                    Thread.sleep(700);
                    System.out.println(Thread.currentThread().getName()+" 释放 写锁:"+DateTime.now().toString("yyyy-MM-dd HH:mm:ss"));
                    tempSLock.unlockWrite(tempStamp);
                }
            } catch (Exception err) {
                System.out.println(Thread.currentThread().getName()+",执行Runnable异常:"+err.getMessage());
            }finally {
                tempStamp=tempSLock.writeLock();
                tempAAA[1]-=1;
                tempSLock.unlockWrite(tempStamp);
            }
        };
        Runnable tempWriteRunnable2= () -> {
            long tempStamp=tempSLock.writeLock();
            tempAAA[1]+=1;
            tempSLock.unlockWrite(tempStamp);
            try {
                for(int i=0;i<50;i++){
                    tempStamp=tempSLock.writeLock();
                    System.out.println(Thread.currentThread().getName()+" 开始 写锁:"+DateTime.now().toString("yyyy-MM-dd HH:mm:ss"));
                    tempAAA[0]+=1;
                    Thread.sleep(1000);
                    System.out.println(Thread.currentThread().getName()+" 释放 写锁:"+DateTime.now().toString("yyyy-MM-dd HH:mm:ss"));
                    tempSLock.unlockWrite(tempStamp);
                }
            } catch (Exception err) {
                System.out.println(Thread.currentThread().getName()+",执行Runnable异常:"+err.getMessage());
            }finally {
                tempStamp=tempSLock.writeLock();
                tempAAA[1]-=1;
                tempSLock.unlockWrite(tempStamp);
            }
        };
        Runnable tempReadRunnable1= () -> {
            try {
                while (tempAAA[1]>0){
                    long tempStamp=tempSLock.readLock();
                    System.out.println(Thread.currentThread().getName()+" 开始 读锁:"+DateTime.now().toString("yyyy-MM-dd HH:mm:ss"));
                    System.out.println(Thread.currentThread().getName()+":"+tempAAA[0]);
                    Thread.sleep(200);
                    System.out.println(Thread.currentThread().getName()+" 释放 读锁:"+DateTime.now().toString("yyyy-MM-dd HH:mm:ss"));
                    tempSLock.unlockRead(tempStamp);
                }
            } catch (Exception err) {
                System.out.println(Thread.currentThread().getName()+",执行Runnable异常:"+err.getMessage());
            }
        };
        Runnable tempReadRunnable2= () -> {
            try {
                while (tempAAA[1]>0){
                    long tempStamp=tempSLock.readLock();
                    System.out.println(Thread.currentThread().getName()+" 开始 读锁:"+DateTime.now().toString("yyyy-MM-dd HH:mm:ss"));
                    System.out.println(Thread.currentThread().getName()+":"+tempAAA[0]);
                    Thread.sleep(300);
                    System.out.println(Thread.currentThread().getName()+" 释放 读锁:"+DateTime.now().toString("yyyy-MM-dd HH:mm:ss"));
                    tempSLock.unlockRead(tempStamp);
                }
            } catch (Exception err) {
                System.out.println(Thread.currentThread().getName()+",执行Runnable异常:"+err.getMessage());
            }
        };
        Thread tempThread1=new Thread(tempWriteRunnable1,"tempThread1");
        Thread tempThread2=new Thread(tempWriteRunnable2,"tempThread2");
        Thread tempThread3=new Thread(tempReadRunnable1,"tempThread3");
        Thread tempThread4=new Thread(tempReadRunnable2,"tempThread4");
        tempThread1.start();
        tempThread2.start();
        tempThread3.start();
        tempThread4.start();

输出:
tempThread1 开始 写锁:2024-05-30 10:06:48
tempThread1 释放 写锁:2024-05-30 10:06:48...
tempThread1 开始 写锁:2024-05-30 10:06:57
tempThread1 释放 写锁:2024-05-30 10:06:58
tempThread3 开始 读锁:2024-05-30 10:06:58
tempThread3:14
tempThread4 开始 读锁:2024-05-30 10:06:58
tempThread4:14
tempThread3 释放 读锁:2024-05-30 10:06:58
tempThread4 释放 读锁:2024-05-30 10:06:58
tempThread2 开始 写锁:2024-05-30 10:06:58
tempThread2 释放 写锁:2024-05-30 10:06:59
tempThread1 开始 写锁:2024-05-30 10:06:59
tempThread1 释放 写锁:2024-05-30 10:07:00...
tempThread1 开始 写锁:2024-05-30 10:07:04
tempThread1 释放 写锁:2024-05-30 10:07:04
tempThread4 开始 读锁:2024-05-30 10:07:04
tempThread4:23
tempThread3 开始 读锁:2024-05-30 10:07:04
tempThread3:23
tempThread3 释放 读锁:2024-05-30 10:07:05
tempThread4 释放 读锁:2024-05-30 10:07:05
tempThread2 开始 写锁:2024-05-30 10:07:05
tempThread2 释放 写锁:2024-05-30 10:07:06...
tempThread1 开始 写锁:2024-05-30 10:07:10
tempThread1 释放 写锁:2024-05-30 10:07:10...
tempThread1 开始 写锁:2024-05-30 10:07:15
tempThread1 释放 写锁:2024-05-30 10:07:15
tempThread3 开始 读锁:2024-05-30 10:07:15
tempThread3:36
tempThread4 开始 读锁:2024-05-30 10:07:15
tempThread4:36
tempThread3 释放 读锁:2024-05-30 10:07:16
tempThread4 释放 读锁:2024-05-30 10:07:16
tempThread2 开始 写锁:2024-05-30 10:07:16
tempThread2 释放 写锁:2024-05-30 10:07:17...
tempThread3 开始 读锁:2024-05-30 10:08:15
tempThread3:99
tempThread4 开始 读锁:2024-05-30 10:08:15
tempThread4:99
tempThread3 释放 读锁:2024-05-30 10:08:16
tempThread4 释放 读锁:2024-05-30 10:08:16
tempThread2 开始 写锁:2024-05-30 10:08:16
tempThread2 释放 写锁:2024-05-30 10:08:17
tempThread4 开始 读锁:2024-05-30 10:08:17
tempThread3 开始 读锁:2024-05-30 10:08:17
tempThread4:100
tempThread3:100
tempThread3 释放 读锁:2024-05-30 10:08:17
tempThread4 释放 读锁:2024-05-30 10:08:17

 

 

 

乐观锁测试:tryOptimisticRead

        int[] tempAAA=new int[]{0,0};
        StampedLock tempSLock=new StampedLock();
        Runnable tempWriteRunnable1= () -> {
            long tempStamp=tempSLock.writeLock();
            tempAAA[1]+=1;
            tempSLock.unlockWrite(tempStamp);
            try {
                for(int i=0;i<50;i++){
                    tempStamp=tempSLock.writeLock();
                    System.out.println(Thread.currentThread().getName()+" 开始 写锁:"+DateTime.now().toString("yyyy-MM-dd HH:mm:ss"));
                    tempAAA[0]+=1;
                    Thread.sleep(700);
                    System.out.println(Thread.currentThread().getName()+" 释放 写锁:"+DateTime.now().toString("yyyy-MM-dd HH:mm:ss"));
                    tempSLock.unlockWrite(tempStamp);
                }
            } catch (Exception err) {
                System.out.println(Thread.currentThread().getName()+",执行Runnable异常:"+err.getMessage());
            }finally {
                tempStamp=tempSLock.writeLock();
                tempAAA[1]-=1;
                tempSLock.unlockWrite(tempStamp);
            }
        };
        Runnable tempWriteRunnable2= () -> {
            long tempStamp=tempSLock.writeLock();
            tempAAA[1]+=1;
            tempSLock.unlockWrite(tempStamp);
            try {
                for(int i=0;i<50;i++){
                    tempStamp=tempSLock.writeLock();
                    System.out.println(Thread.currentThread().getName()+" 开始 写锁:"+DateTime.now().toString("yyyy-MM-dd HH:mm:ss"));
                    tempAAA[0]+=1;
                    Thread.sleep(1000);
                    System.out.println(Thread.currentThread().getName()+" 释放 写锁:"+DateTime.now().toString("yyyy-MM-dd HH:mm:ss"));
                    tempSLock.unlockWrite(tempStamp);
                }
            } catch (Exception err) {
                System.out.println(Thread.currentThread().getName()+",执行Runnable异常:"+err.getMessage());
            }finally {
                tempStamp=tempSLock.writeLock();
                tempAAA[1]-=1;
                tempSLock.unlockWrite(tempStamp);
            }
        };
        Runnable tempReadRunnable1= () -> {
            try {
                while (tempAAA[1]>0){
                    long tempStamp=tempSLock.tryOptimisticRead();
                    System.out.println(Thread.currentThread().getName()+" 开始 读锁:"+DateTime.now().toString("yyyy-MM-dd HH:mm:ss"));
                    System.out.println(Thread.currentThread().getName()+":"+tempAAA[0]);
                    Thread.sleep(200);
                    if(tempSLock.validate(tempStamp)){
                        System.out.println(Thread.currentThread().getName()+" 释放 读锁:"+DateTime.now().toString("yyyy-MM-dd HH:mm:ss"));
                        tempSLock.unlock(tempStamp);
                    }
                }
            } catch (Exception err) {
                System.out.println(Thread.currentThread().getName()+",执行Runnable异常:"+err.getMessage());
            }
        };
        Runnable tempReadRunnable2= () -> {
            try {
                while (tempAAA[1]>0){
                    long tempStamp=tempSLock.tryOptimisticRead();
                    System.out.println(Thread.currentThread().getName()+" 开始 读锁:"+DateTime.now().toString("yyyy-MM-dd HH:mm:ss"));
                    System.out.println(Thread.currentThread().getName()+":"+tempAAA[0]);
                    Thread.sleep(300);
                    if(tempSLock.validate(tempStamp)){
                        System.out.println(Thread.currentThread().getName()+" 释放 读锁:"+DateTime.now().toString("yyyy-MM-dd HH:mm:ss"));
                        tempSLock.unlock(tempStamp);
                    }
                }
            } catch (Exception err) {
                System.out.println(Thread.currentThread().getName()+",执行Runnable异常:"+err.getMessage());
            }
        };
        Thread tempThread1=new Thread(tempWriteRunnable1,"tempThread1");
        Thread tempThread2=new Thread(tempWriteRunnable2,"tempThread2");
        Thread tempThread3=new Thread(tempReadRunnable1,"tempThread3");
        Thread tempThread4=new Thread(tempReadRunnable2,"tempThread4");
        tempThread1.start();
        tempThread2.start();
        tempThread3.start();
        tempThread4.start();

输出:

tempThread1 开始 写锁:2024-05-30 09:57:25
tempThread3 开始 读锁:2024-05-30 09:57:25
tempThread4 开始 读锁:2024-05-30 09:57:25
tempThread4:1
tempThread3:1
tempThread3 开始 读锁:2024-05-30 09:57:25
tempThread3:1
tempThread4 开始 读锁:2024-05-30 09:57:25
tempThread4:1
tempThread3 开始 读锁:2024-05-30 09:57:25
tempThread3:1
tempThread4 开始 读锁:2024-05-30 09:57:25
tempThread4:1
tempThread3 开始 读锁:2024-05-30 09:57:25
tempThread3:1
tempThread1 释放 写锁:2024-05-30 09:57:25
tempThread1 开始 写锁:2024-05-30 09:57:25
tempThread3 开始 读锁:2024-05-30 09:57:26
tempThread3:2
tempThread4 开始 读锁:2024-05-30 09:57:26
tempThread4:2
......
tempThread3 开始 读锁:2024-05-30 09:57:27
tempThread3:3
tempThread3 开始 读锁:2024-05-30 09:57:27
tempThread3:3
tempThread1 释放 写锁:2024-05-30 09:57:27
tempThread2 开始 写锁:2024-05-30 09:57:27
tempThread4 开始 读锁:2024-05-30 09:57:27
tempThread4:4
tempThread3 开始 读锁:2024-05-30 09:57:27
tempThread3:4
tempThread4 开始 读锁:2024-05-30 09:57:27
tempThread4:4
....
tempThread3 开始 读锁:2024-05-30 09:57:28
tempThread3:4
tempThread4 开始 读锁:2024-05-30 09:57:28
tempThread4:4
tempThread3 开始 读锁:2024-05-30 09:57:28
tempThread3:4
tempThread2 释放 写锁:2024-05-30 09:57:28
tempThread2 开始 写锁:2024-05-30 09:57:28
tempThread3 开始 读锁:2024-05-30 09:57:28
tempThread3:5
tempThread4 开始 读锁:2024-05-30 09:57:28
tempThread4:5
...
tempThread3 开始 读锁:2024-05-30 09:57:31
tempThread3:8
tempThread1 释放 写锁:2024-05-30 09:57:32
tempThread1 开始 写锁:2024-05-30 09:57:32
tempThread3 开始 读锁:2024-05-30 09:57:32
tempThread3:9
tempThread4 开始 读锁:2024-05-30 09:57:32
tempThread4:9

...
tempThread3 开始 读锁:2024-05-30 09:58:49
tempThread3:99
tempThread4 开始 读锁:2024-05-30 09:58:49
tempThread4:99
tempThread3 开始 读锁:2024-05-30 09:58:49
tempThread3:99
tempThread3 开始 读锁:2024-05-30 09:58:50
tempThread3:99
tempThread1 释放 写锁:2024-05-30 09:58:50
tempThread1 开始 写锁:2024-05-30 09:58:50
tempThread4 开始 读锁:2024-05-30 09:58:50
tempThread4:100
tempThread3 开始 读锁:2024-05-30 09:58:50
tempThread3:100
tempThread4 开始 读锁:2024-05-30 09:58:50
tempThread4:100
tempThread3 开始 读锁:2024-05-30 09:58:50
tempThread3:100
tempThread3 开始 读锁:2024-05-30 09:58:50
tempThread3:100
tempThread4 开始 读锁:2024-05-30 09:58:50
tempThread4:100
tempThread1 释放 写锁:2024-05-30 09:58:50

 

 

synchronized


        Runnable tempRunnable1= () -> {
            try {
                for(int i=0;i<50;i++){
                    synchronized (this){
                        System.out.println(Thread.currentThread().getName()+" 开始 写锁:"+DateTime.now().toString("yyyy-MM-dd HH:mm:ss"));
                        Thread.sleep(700);
                        System.out.println(Thread.currentThread().getName()+" 释放 写锁:"+DateTime.now().toString("yyyy-MM-dd HH:mm:ss"));
                    }
                }
            } catch (Exception err) {
                System.out.println(Thread.currentThread().getName()+",执行Runnable异常:"+err.getMessage());
            }
        };
        Runnable tempRunnable2= () -> {
            try {
                for(int i=0;i<50;i++){
                    synchronized (this){
                        System.out.println(Thread.currentThread().getName()+" 开始 写锁:"+DateTime.now().toString("yyyy-MM-dd HH:mm:ss"));
                        Thread.sleep(700);
                        System.out.println(Thread.currentThread().getName()+" 释放 写锁:"+DateTime.now().toString("yyyy-MM-dd HH:mm:ss"));
                    }
                }
            } catch (Exception err) {
                System.out.println(Thread.currentThread().getName()+",执行Runnable异常:"+err.getMessage());
            }
        };
        Thread tempThread1=new Thread(tempRunnable1,"tempThread1");
        Thread tempThread2=new Thread(tempRunnable2,"tempThread2");
        tempThread1.start();
        tempThread2.start();

输出:

tempThread1 开始 写锁:2024-05-30 10:18:32
tempThread1 释放 写锁:2024-05-30 10:18:33
tempThread2 开始 写锁:2024-05-30 10:18:33
tempThread2 释放 写锁:2024-05-30 10:18:34
...
tempThread2 开始 写锁:2024-05-30 10:19:31
tempThread2 释放 写锁:2024-05-30 10:19:32
tempThread1 开始 写锁:2024-05-30 10:19:32
tempThread1 释放 写锁:2024-05-30 10:19:33

...


 


 




待续...