详情请参照,本文仅作笔记记录:阿里二面: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
...
待续...