一 、getHoldCount() 、getQueueLength()、getWaitQueueLength()
(一)、getHoldCount() 是当前线程调用lock方法的次数。
package com.it.po.thread11.thread11_1; import java.util.concurrent.locks.ReentrantLock; public class Service1 { private ReentrantLock lock =new ReentrantLock(); public void methodA(){ lock.lock(); System.out.println("methodA getHoldCount "+lock.getHoldCount()); methodB(); lock.unlock(); } public void methodB(){ lock.lock(); System.out.println("methodB getHoldCount "+lock.getHoldCount()); lock.unlock(); } }
package com.it.po.thread11.thread11_1; public class Run1 { public static void main(String[] args) { new Service1().methodA(); } }
(二)、getQueueLength()
作用是返回正等待获取此锁定的线程估计数。
比如有5个线程,一个线程先执行await(),那么在调用getQueueLength()时
返回值是4,说明有4个线程在等待lock的释放。
package com.it.po.thread11.thread11_1; import java.util.concurrent.locks.ReentrantLock; public class Service2 { public ReentrantLock lock =new ReentrantLock(); public void methodA(){ try { lock.lock(); System.out.println("线程 "+Thread.currentThread().getName()+" 进入了方法"); Thread.sleep(Integer.MAX_VALUE); } catch (InterruptedException e) { e.printStackTrace(); }finally { lock.unlock(); } } }
package com.it.po.thread11.thread11_1; public class Run2 { public static void main(String[] args) throws InterruptedException { Service2 service= new Service2(); Runnable runnable = new Runnable() { @Override public void run() { System.out.println("**线程 "+Thread.currentThread().getName()+" 运行了"); service.methodA(); } }; Thread[] threads = new Thread[10]; for(int i=0;i<10;i++){ threads[i]=new Thread(runnable); threads[i].setName(""+(i+1)); } for(int i=0;i<10;i++){ threads[i].start(); } Thread.sleep(2000); System.out.println("正有 "+service.lock.getQueueLength()+" 个线程等待获取锁"); } }
**线程 1 运行了 **线程 3 运行了 线程 1 进入了方法 **线程 5 运行了 **线程 4 运行了 **线程 2 运行了 **线程 6 运行了 **线程 7 运行了 **线程 8 运行了 **线程 9 运行了 **线程 10 运行了 正有 9 个线程等待获取锁
(三)、getWaitQueueLength( Condition condition)
作用是返回等待与此锁相关的给定条件Condition的线程估计数。
如5个线程,每一个线程都执行了同一个condition对象的await()方法
则调用getWaitQueueLength( Condition condition) 返回的值int为5
package com.it.po.thread11.thread11_1; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReentrantLock; public class Service3 { public ReentrantLock lock =new ReentrantLock(); private Condition condition=lock.newCondition(); public void methodA(){ try { lock.lock(); condition.await(); } catch (InterruptedException e) { e.printStackTrace(); }finally { lock.unlock(); } } public void methodB(){ try { lock.lock(); System.out.println("有1 "+lock.getWaitQueueLength(condition)+" 正在等condition"); condition.signal(); System.out.println("有2 "+lock.getWaitQueueLength(condition)+" 正在等condition"); } finally { lock.unlock(); } } }
package com.it.po.thread11.thread11_1; public class Run3 { public static void main(String[] args) throws InterruptedException { Service3 service= new Service3(); Runnable runnable = new Runnable() { @Override public void run() { service.methodA(); } }; Thread[] threads = new Thread[10]; for(int i=0;i<10;i++){ threads[i]=new Thread(runnable); } for(int i=0;i<10;i++){ threads[i].start(); } Thread.sleep(2000); service.methodB(); } }
有1 10 正在等condition 有2 9 正在等condition
修改一下
package com.it.po.thread11.thread11_1; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReentrantLock; public class Service3 { public ReentrantLock lock =new ReentrantLock(); private Condition condition=lock.newCondition(); public void methodA(){ try { lock.lock(); condition.await(); } catch (InterruptedException e) { e.printStackTrace(); }finally { lock.unlock(); } } public void methodB(){ try { lock.lock(); System.out.println("有1 "+lock.getWaitQueueLength(condition)+" 正在等condition"); condition.signalAll(); System.out.println("有2 "+lock.getWaitQueueLength(condition)+" 正在等condition"); } finally { lock.unlock(); } } }
有1 10 正在等condition 有2 0 正在等condition
二、方法hasQueueThread() 、hasQueueThreads 、hasWaiters()
(一)、hasQueueThread()
boolean hasQueueThread(Thread thread) 查询指定的线程
是否正在等待获取此锁定。
boolean hasQueueThreads(Thread thread) 查询是否有线程正在等待
获取此锁定。
package com.it.po.thread11.thread11_1; import java.util.concurrent.locks.ReentrantLock; public class Service4 { public ReentrantLock lock =new ReentrantLock(); public void methodA(){ try { lock.lock(); System.out.println("线程 "+Thread.currentThread().getName()+" 进入了方法"); Thread.sleep(Integer.MAX_VALUE); } catch (InterruptedException e) { e.printStackTrace(); }finally { lock.unlock(); } } }
package com.it.po.thread11.thread11_1; public class Run4 { public static void main(String[] args) throws InterruptedException { Service4 service= new Service4(); Runnable runnable = new Runnable() { @Override public void run() { service.methodA(); } }; Thread t1 = new Thread(runnable); t1.setName("A"); t1.start(); Thread.sleep(500); Thread t2 = new Thread(runnable); t2.setName("B"); t2.start(); Thread.sleep(500); System.out.println("t1: "+service.lock.hasQueuedThread(t1)); System.out.println("t2:"+service.lock.hasQueuedThread(t2)); System.out.println("哈哈:"+service.lock.hasQueuedThreads()); } }

线程 A 进入了方法 t1: false t2:true 哈哈:true
(二)、boolean hasWaiters(Condition condition )
作用就是查询是否有线程正在等待与此锁定有关的condition
package com.it.po.thread11.thread11_1; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReentrantLock; public class Service5 { public ReentrantLock lock =new ReentrantLock(); private Condition condition=lock.newCondition(); public void methodA(){ try { lock.lock(); condition.await(); } catch (InterruptedException e) { e.printStackTrace(); }finally { lock.unlock(); } } public void methodB(){ try { lock.lock(); System.out.println("begin 有 "+lock.hasWaiters(condition)+ " 线程数是 "+lock.getWaitQueueLength(condition)); condition.signal(); System.out.println("end 有 "+lock.hasWaiters(condition)+ " 线程数是 "+lock.getWaitQueueLength(condition)); } finally { lock.unlock(); } } }
package com.it.po.thread11.thread11_1; public class Run5 { public static void main(String[] args) throws InterruptedException { Service5 service= new Service5(); Runnable runnable = new Runnable() { @Override public void run() { service.methodA(); } }; Thread[] threads = new Thread[10]; for(int i=0;i<10;i++){ threads[i]=new Thread(runnable); } for(int i=0;i<10;i++){ threads[i].start(); } Thread.sleep(2000); service.methodB(); } }

begin 有 true 线程数是 10 end 有 true 线程数是 9
三、方法isFair() 、isHeldByCurrentThread()、 isLocked()
(一)
boolean isFair() 判断是不是公平锁‘
package com.it.po.thread11.thread11_1; import java.util.concurrent.locks.ReentrantLock; public class Service6 { private ReentrantLock lock =null; public Service6(Boolean isFair) { lock = new ReentrantLock(isFair); } public void methodA(){ try { lock.lock(); System.out.println("是不是公平锁 "+lock.isFair()); }finally { lock.unlock(); } } }
’
package com.it.po.thread11.thread11_1; public class Run6 { public static void main(String[] args) { new Service6(true).methodA(); } }
是不是公平锁 true
(二)、isHeldByCurrentThread()
boolean isHeldByCurrentThread() 查询当前线程是否保存此锁定
package com.it.po.thread11.thread11_1; import java.util.concurrent.locks.ReentrantLock; public class Service7 { private ReentrantLock lock =null; public Service7(Boolean isFair) { lock = new ReentrantLock(isFair); } public void methodA(){ try { String name = Thread.currentThread().getName(); System.out.println("线程lock begin "+name +" "+lock.isHeldByCurrentThread()); lock.lock(); System.out.println("线程lock end "+name +" "+lock.isHeldByCurrentThread()); }finally { lock.unlock(); } } }
package com.it.po.thread11.thread11_1; public class Run7 { public static void main(String[] args) throws InterruptedException { Service7 service= new Service7(true); Runnable runnable = new Runnable() { @Override public void run() { service.methodA(); } }; Thread t1 = new Thread(runnable); t1.setName("A"); t1.start(); Thread.sleep(500); Thread t2 = new Thread(runnable); t2.setName("B"); t2.start(); } }
线程lock begin A false 线程lock end A true 线程lock begin B false 线程lock end B true
(三)isLocked()
boolean isLocked()
查询此锁定是否是由任意线程保持
package com.it.po.thread11.thread11_1; import java.util.concurrent.locks.ReentrantLock; public class Service8 { private ReentrantLock lock =null; public Service8(Boolean isFair) { lock = new ReentrantLock(isFair); } public void methodA(){ try { System.out.println(lock.isLocked()); lock.lock(); System.out.println(lock.isLocked()); }finally { lock.unlock(); } } }
package com.it.po.thread11.thread11_1; public class Run8 { public static void main(String[] args) { Service8 service= new Service8(false); Runnable runnable = new Runnable() { @Override public void run() { service.methodA(); } }; new Thread(runnable).start(); } }
false true
四、方法lockInterruptibly()、tryLock()、tryLock(long timeout,TimeUnit unit)
(一)、lockInterruptibly()
void lockInterruptibly() 的作用是如果当前线程未被中断,则获锁定
如果已经被中断,则出现异常。
package com.it.po.thread11.thread11_1; import java.util.concurrent.locks.ReentrantLock; public class Service9 { private ReentrantLock lock =new ReentrantLock();; public void methodA(){ try { lock.lockInterruptibly(); System.out.println("线程 begin "+Thread.currentThread().getName()); for(int i=0;i<10000;i++){ String s = new String(); Math.random(); } System.out.println("线程 end "+Thread.currentThread().getName()); }catch (InterruptedException e){ e.printStackTrace(); } finally { if(lock.isHeldByCurrentThread()) { System.out.println("线程 "+Thread.currentThread().getName()+" 释放锁"); lock.unlock(); } } } }
package com.it.po.thread11.thread11_1; public class Run9 { public static void main(String[] args) throws InterruptedException { final Service9 service= new Service9(); Runnable runnable = new Runnable() { @Override public void run() { service.methodA(); } }; Thread t1 = new Thread(runnable); t1.setName("A"); t1.start(); Thread.sleep(2); Thread t2 = new Thread(runnable); t2.setName("B"); t2.start(); // t2.interrupt();//打标记 Thread.sleep(1000); System.out.println("end main"); } }
线程 begin A
线程 end A
线程 A 释放锁
线程 begin B
线程 end B
线程 B 释放锁
end main
修改
package com.it.po.thread11.thread11_1; public class Run9 { public static void main(String[] args) throws InterruptedException { final Service9 service= new Service9(); Runnable runnable = new Runnable() { @Override public void run() { service.methodA(); } }; Thread t1 = new Thread(runnable); t1.setName("A"); t1.start(); Thread.sleep(2); Thread t2 = new Thread(runnable); t2.setName("B"); t2.start(); t2.interrupt();//打标记 Thread.sleep(1000); System.out.println("end main"); } }
线程 begin A 线程 end A 线程 A 释放锁 java.lang.InterruptedException at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireInterruptibly(AbstractQueuedSynchronizer.java:1220) at java.util.concurrent.locks.ReentrantLock.lockInterruptibly(ReentrantLock.java:335) at com.it.po.thread11.thread11_1.Service9.methodA(Service9.java:7) at com.it.po.thread11.thread11_1.Run9$1.run(Run9.java:8) at java.lang.Thread.run(Thread.java:748) end main
线程B获得锁,但是被中断,抛出异常
(二)、tryLock
仅在调用时锁定未被另一个线程保持的情况下,才获取该锁定。
package com.it.po.thread11.thread11_1; import java.util.concurrent.locks.ReentrantLock; public class Service10 { private ReentrantLock lock =new ReentrantLock(); public void methodA(){ if(lock.tryLock()){ System.out.println(Thread.currentThread().getName()+" 获得锁"); }else { System.out.println(Thread.currentThread().getName()+" 没有获得锁"); } } }
package com.it.po.thread11.thread11_1; public class Run10 { public static void main(String[] args) throws InterruptedException { final Service10 service= new Service10(); Runnable runnable = new Runnable() { @Override public void run() { service.methodA(); } }; Thread t1 = new Thread(runnable); t1.setName("A"); t1.start(); Thread t2 = new Thread(runnable); t2.setName("B"); t2.start(); } }
B 获得锁
A 没有获得锁
结果是不定的
(三)、tryLock(long timeout,TimeUnit unit)
如果锁定在给定的等待时间内没有被另一个线程保持,且当前线程未被中断
则获取该线程。
package com.it.po.thread11.thread11_1; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.ReentrantLock; public class Service11 { private ReentrantLock lock =new ReentrantLock(); public void methodA(){ try { if(lock.tryLock(3, TimeUnit.SECONDS)){ System.out.println(Thread.currentThread().getName()+" " + "获得锁时间 "+System.currentTimeMillis()); Thread.sleep(8000); }else { System.out.println(Thread.currentThread().getName()+ " 没有获得锁 "+System.currentTimeMillis()); } } catch (InterruptedException e) { e.printStackTrace(); }finally { if(lock.isHeldByCurrentThread()){ System.out.println(Thread.currentThread().getName()+" " + "释放锁时间 "+System.currentTimeMillis()); lock.unlock(); } } } }
package com.it.po.thread11.thread11_1; public class Run11 { public static void main(String[] args) throws InterruptedException { final Service11 service= new Service11(); Runnable runnable = new Runnable() { @Override public void run() { System.out.println(Thread.currentThread().getName()+ " 调用methodA时间 "+System.currentTimeMillis()); service.methodA(); } }; Thread t1 = new Thread(runnable); t1.setName("A"); t1.start(); Thread t2 = new Thread(runnable); t2.setName("B"); t2.start(); } }
A 调用methodA时间 1575722336809 B 调用methodA时间 1575722336810 A 获得锁时间 1575722336811 B 没有获得锁 1575722339812 A 释放锁时间 1575722344811
3s之后线程B才进入else
五、方法awaitUninterruptibly()的使用
package com.it.po.thread11.thread11_1; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class Service12 { private ReentrantLock lock =new ReentrantLock(); private Condition condition =lock.newCondition(); public void methodA(){ try { lock.lock(); System.out.println("await begin..."); condition.await(); System.out.println("await end..."); } catch (InterruptedException e) { e.printStackTrace(); System.out.println("catch lanpo..."); }finally { lock.unlock(); } } }
package com.it.po.thread11.thread11_1; public class Run12 { public static void main(String[] args) throws InterruptedException { Service12 service= new Service12(); Thread1 t1 = new Thread1(service); Thread thread = new Thread(t1); thread.start(); Thread.sleep(3000); thread.interrupt(); } }
await begin... catch lanpo... java.lang.InterruptedException at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.reportInterruptAfterWait(AbstractQueuedSynchronizer.java:2014) at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2048) at com.it.po.thread11.thread11_1.Service12.methodA(Service12.java:13) at com.it.po.thread11.thread11_1.Thread1.run(Thread1.java:11) at java.lang.Thread.run(Thread.java:748)
修改如下,其他不变
package com.it.po.thread11.thread11_1; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class Service12 { private ReentrantLock lock =new ReentrantLock(); private Condition condition =lock.newCondition(); public void methodA(){ try { lock.lock(); System.out.println("await begin..."); //condition.await(); condition.awaitUninterruptibly(); System.out.println("await end..."); } finally { lock.unlock(); } } }

await begin...
六、方法awaitUntil()的使用
package com.it.po.thread11.thread11_1; import java.util.Calendar; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReentrantLock; public class Service13 { private ReentrantLock lock =new ReentrantLock(); private Condition condition =lock.newCondition(); public void methodA(){ try { Calendar calendar = Calendar.getInstance(); calendar.add(Calendar.SECOND,10); lock.lock(); System.out.println("methodA wait begin time "+System.currentTimeMillis()); condition.awaitUntil(calendar.getTime());//10s System.out.println("methodA wait end time "+System.currentTimeMillis()); }catch (InterruptedException e){ e.printStackTrace(); } finally { lock.unlock(); } } public void methodB(){ try { Calendar calendar = Calendar.getInstance(); calendar.add(Calendar.SECOND,10); lock.lock(); System.out.println("methodB wait begin time "+System.currentTimeMillis()); condition.signalAll(); System.out.println("methodB wait end time "+System.currentTimeMillis()); } finally { lock.unlock(); } } }

package com.it.po.thread11.thread11_1; public class Run13 { public static void main(String[] args) throws InterruptedException { Service13 service= new Service13(); MyThread2_1 t1 = new MyThread2_1(service); t1.start(); } }
methodA wait begin time 1575723878519 methodA wait end time 1575723888501
添加如下
package com.it.po.thread11.thread11_1; public class Run13 { public static void main(String[] args) throws InterruptedException { Service13 service= new Service13(); MyThread2_1 t1 = new MyThread2_1(service); t1.start(); Thread.sleep(3000); MyThread2_2 t2 = new MyThread2_2(service); t2.start(); } }
methodA wait begin time 1575724014556 methodB wait begin time 1575724017520 methodB wait end time 1575724017520 methodA wait end time 1575724017520
线程等待时间到达前,可以被其他线程唤醒。
浙公网安备 33010602011771号