源无极

导航

 

一 、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

 

线程等待时间到达前,可以被其他线程唤醒。

 

 

 

 

 

 

 

 

 

 

 

posted on 2019-12-07 13:01  源无极  阅读(1988)  评论(0)    收藏  举报