博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java并发之ReentrantLock学习理解
阅读量:6658 次
发布时间:2019-06-25

本文共 30629 字,大约阅读时间需要 102 分钟。

简介

java多线程中可以使用synchronized关键字来实现线程间同步互斥,但在jdk1.5中新增加了ReentrantLock类也能实现同样的效果,并且在扩展功能上也更加强大,比如具有嗅探锁定、多路通知分支等功能,并且使用上比synchronized更加灵活。

如何使用ReentrantLock

主要是lock.lock()lock.unlock()两个方法

1 public class MyService implements Runnable { 2      3     protected ReentrantLock lock; 4      5     public MyService(ReentrantLock lock){ 6         this.lock = lock; 7     } 8  9     public void run() {10         lock.lock();11         for (int i = 0; i < 5; i++) {12             System.out.println(Thread.currentThread().getName()+" "+i);13             try {14                 Thread.sleep(1000);15             } catch (InterruptedException e) {16                 e.printStackTrace();17             }18         }19         lock.unlock();20     }21 22 }
1 /** 2  * 测试类 3  * @author ko 4  * 5  */ 6 public class Test { 7  8     public static void main(String[] args) { 9         ReentrantLock lock = new ReentrantLock();10         for (int i = 0; i < 4; i++) {11             new Thread(new MyService(lock)).start();12         }13     }14 }
Thread-0 0Thread-0 1Thread-0 2Thread-0 3Thread-0 4Thread-1 0Thread-1 1Thread-1 2Thread-1 3Thread-1 4Thread-2 0Thread-2 1Thread-2 2Thread-2 3Thread-2 4Thread-3 0Thread-3 1Thread-3 2Thread-3 3Thread-3 4

使用Condition类实现wait、notify的功能

Condition类也是jdk1.5里出来的,它能实现synchronized和wait、notify搭配的功能,另外比后者更灵活,Condition可以实现多路通知功能,也就是在一个Lock对象里可以创建多个Condition(即对象监视器)实例,线程对象可以注册在指定的Condition中,从而可以有选择的进行线程通知,在调度线程上更加灵活

而synchronized就相当于整个Lock对象中只有一个单一的Condition对象,所有的线程都注册在这个对象上。线程开始notifyAll时,需要通知所有的WAITING线程,没有选择权,会有相当大的效率问题。

使用Condition为什么会报java.lang.IllegalMonitorStateException异常

还是刚才的代码,稍作改动

1 public class MyService implements Runnable { 2      3     protected ReentrantLock lock; 4     protected Condition condition; 5      6     public MyService(ReentrantLock lock,Condition condition){ 7         this.lock = lock; 8         this.condition = condition; 9     }10 11     public void run() {12 //        lock.lock();13         try {14             condition.await();15         } catch (InterruptedException e1) {16             // TODO Auto-generated catch block17             e1.printStackTrace();18         }19         for (int i = 0; i < 5; i++) {20             System.out.println(Thread.currentThread().getName()+" "+i);21             try {22                 Thread.sleep(1000);23             } catch (InterruptedException e) {24                 e.printStackTrace();25             }26         }27 //        lock.unlock();28     }29 30 }
1 /** 2  * 测试类 3  * @author ko 4  * 5  */ 6 public class Test { 7  8     public static void main(String[] args) { 9         ReentrantLock lock = new ReentrantLock();10         Condition condition = lock.newCondition();11         for (int i = 0; i < 4; i++) {12             new Thread(new MyService(lock,condition)).start();13         }14     }15 }
Exception in thread "Thread-0" Exception in thread "Thread-1" Exception in thread "Thread-2" Exception in thread "Thread-3" java.lang.IllegalMonitorStateException	at java.util.concurrent.locks.ReentrantLock$Sync.tryRelease(Unknown Source)	at java.util.concurrent.locks.AbstractQueuedSynchronizer.release(Unknown Source)	at java.util.concurrent.locks.AbstractQueuedSynchronizer.fullyRelease(Unknown Source)	at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(Unknown Source)	at ww.MyService.run(MyService.java:26)	at java.lang.Thread.run(Unknown Source)

  报错的异常信息是监视器出错,原因是在调用condition.await()之前是要先调用lock.lock()来获得同步监视器

正确使用Condition类

1 public class MyService implements Runnable { 2      3     protected ReentrantLock lock; 4     protected Condition condition; 5      6     public MyService(ReentrantLock lock,Condition condition){ 7         this.lock = lock; 8         this.condition = condition; 9     }10     11     public void await(){12         try {13             lock.lock();14             System.out.println("await time is "+System.currentTimeMillis());15             condition.await();16             System.out.println("after await info...");17         } catch (InterruptedException e1) {18             e1.printStackTrace();19         } finally {20             lock.unlock();21         }22     }23     24     public void signal(){25         try {26             lock.lock();27             System.out.println("signal time is "+System.currentTimeMillis());28             condition.signal();29         } finally {30             lock.unlock();31         }32     }33 34     public void run() {35         await();36     }37 38 }
1 /** 2  * 测试类 3  * @author ko 4  * 5  */ 6 public class Test { 7  8     public static void main(String[] args) { 9         ReentrantLock lock = new ReentrantLock();10         Condition condition = lock.newCondition();11         MyService service = new MyService(lock,condition);12         new Thread(service).start();13         try {14             Thread.sleep(3000);15         } catch (InterruptedException e) {16             e.printStackTrace();17         }18         service.signal();19     }20 }
await time is 1501142954379signal time is 1501142957381after await info...

 成功实现等待通知模式,整理一下,下表的方法功能是对应的

Object

Condition

Wait()

Await()

Wait(long timeout)

Await(long time,TimeUnit unit)

Notify()

Signal()

notifyAll()

signalAll()

使用多个Condition实现通知部分线程

 

1 public class MyService implements Runnable { 2      3     protected ReentrantLock lock; 4     protected Condition conditionA; 5     protected Condition conditionB; 6      7     public MyService(ReentrantLock lock,Condition conditionA,Condition conditionB){ 8         this.lock = lock; 9         this.conditionA = conditionA;10         this.conditionB = conditionB;11     }12     13     public void await_A(){14         try {15             lock.lock();16             System.out.println(Thread.currentThread().getName()+" await_A time is "+System.currentTimeMillis());17             conditionA.await();18             System.out.println(Thread.currentThread().getName()+" after await_A info...");19         } catch (InterruptedException e1) {20             e1.printStackTrace();21         } finally {22             lock.unlock();23         }24     }25     26     public void await_B(){27         try {28             lock.lock();29             System.out.println(Thread.currentThread().getName()+" await_B time is "+System.currentTimeMillis());30             conditionB.await();31             System.out.println(Thread.currentThread().getName()+" after_B await info...");32         } catch (InterruptedException e1) {33             e1.printStackTrace();34         } finally {35             lock.unlock();36         }37     }38     39     public void signal_A(){40         try {41             lock.lock();42             System.out.println(Thread.currentThread().getName()+" signal_A time is "+System.currentTimeMillis());43             conditionA.signal();44         } finally {45             lock.unlock();46         }47     }48 49     public void signal_B(){50         try {51             lock.lock();52             System.out.println(Thread.currentThread().getName()+" signal_B time is "+System.currentTimeMillis());53             conditionB.signal();54         } finally {55             lock.unlock();56         }57     }58     59     public void run() {60         String tname = Thread.currentThread().getName();61         if (tname.equals("A")) {62             await_A();63         } else if (tname.equals("B")) {64             await_B();65         }66     }67 68 }
1 /** 2  * 测试类 3  * @author ko 4  * 5  */ 6 public class Test { 7  8     public static void main(String[] args) { 9         ReentrantLock lock = new ReentrantLock();10         11         Condition conditionA = lock.newCondition();12         Condition conditionB = lock.newCondition();13         MyService service = new MyService(lock,conditionA,conditionB);14         15         Thread tA = new Thread(service);16         tA.setName("A");17         tA.start();18         19         Thread tB = new Thread(service);20         tB.setName("B");21         tB.start();22         23         try {24             Thread.sleep(3000);25         } catch (InterruptedException e) {26             e.printStackTrace();27         }28         29         service.signal_A();30     }31 }
A await_A time is 1501482321344B await_B time is 1501482321346main signal_A time is 1501482324344A after await_A info...

可以看到只唤醒了A线程。。。

一对一的生产者消费者  

1 /** 2  * 生产者和消费者一对一 3  * @author ko 4  * 5  */ 6 public class MyService { 7      8     protected ReentrantLock lock = new ReentrantLock(); 9     protected Condition condition = lock.newCondition();10     protected boolean hasValue = false;11     12     public void set(){13         try {14             lock.lock();15             while (hasValue == true) {16                 condition.await();17             }18             System.out.println("★");19             hasValue = true;20             condition.signal();21         } catch (InterruptedException e) {22             // TODO Auto-generated catch block23             e.printStackTrace();24         } finally {25             lock.unlock();26         }27     }28     29     public void get(){30         try {31             lock.lock();32             while (hasValue == false) {33                 condition.await();34             }35             System.out.println("☆");36             hasValue = false;37             condition.signal();38         } catch (InterruptedException e) {39             // TODO Auto-generated catch block40             e.printStackTrace();41         } finally {42             lock.unlock();43         }44     }45     46 }
1 /** 2  * 生产者 3  * @author ko 4  * 5  */ 6 public class Producer implements Runnable { 7  8     protected MyService myService; 9     10     public Producer(MyService myService) {11         super();12         this.myService = myService;13     }14 15     public void run() {16         for (int i = 0; i < Integer.MAX_VALUE; i++) {17             myService.set();18         }19     }20 21 }
1 /** 2  * 消费者 3  * @author ko 4  * 5  */ 6 public class Customer implements Runnable { 7  8     protected MyService myService; 9     10     public Customer(MyService myService) {11         super();12         this.myService = myService;13     }14 15     public void run() {16         for (int i = 0; i < Integer.MAX_VALUE; i++) {17             myService.get();18         }19     }20 21 }
1 /** 2  * 测试类 3  * @author ko 4  * 5  */ 6 public class Test { 7  8     public static void main(String[] args) { 9         MyService myService = new MyService();10         Producer p = new Producer(myService);11         Customer c = new Customer(myService);12         13         new Thread(p).start();14         new Thread(c).start();15         16     }17 }

打印结果

多对多的生产者消费者

1 /** 2  * 测试类 3  * @author ko 4  * 5  */ 6 public class Test { 7  8     public static void main(String[] args) { 9         MyService myService = new MyService();10         11         for (int i = 0; i < 10; i++) {12             new Thread(new Producer(myService)).start();13             new Thread(new Customer(myService)).start();14         }15         16     }17 }
1 /** 2  * 生产者和消费者多对多 3  * @author ko 4  * 5  */ 6 public class MyService { 7      8     protected ReentrantLock lock = new ReentrantLock(); 9     protected Condition condition = lock.newCondition();10     protected boolean hasValue = false;11     12     public void set(){13         try {14             lock.lock();15             while (hasValue == true) {16                 System.out.println("有可能★连续打印");17                 condition.await();18             }19             System.out.println("★");20             hasValue = true;21             condition.signalAll();22         } catch (InterruptedException e) {23             // TODO Auto-generated catch block24             e.printStackTrace();25         } finally {26             lock.unlock();27         }28     }29     30     public void get(){31         try {32             lock.lock();33             while (hasValue == false) {34                 System.out.println("有可能☆连续打印");35                 condition.await();36             }37             System.out.println("☆");38             hasValue = false;39             condition.signalAll();40         } catch (InterruptedException e) {41             // TODO Auto-generated catch block42             e.printStackTrace();43         } finally {44             lock.unlock();45         }46     }47     48 }

要注意的是由于现在是多个生产者消费者,所以condition.signal()要改为condition.signalAll(),其它代码不变。

查看打印结果,发现★和☆总是间隔打印,但是 有可能★连续打印 和 有可能☆连续打印 却有可能连续打印,这是因为改为signalAll后唤醒的是所有线程,有可能再次把自己唤醒,所以会出现这种情况。

公平锁与非公平锁

公平锁表示线程获取锁的顺序是按照线程加锁的顺序来分配的,而非公平锁是一种抢占机制,随机的。

还是上面的代码,给ReentrantLock换个有isFair参数的构造方法,new ReentrantLock(isFair) true就是公平锁,false就是非公平锁。再给打印的语句加上线程名,当为true时,线程是按顺序打印,为false时随机打印。

 

 方法getHoldCount()的使用

getHoldCount()表示当前线程获取锁的个数

1 public class MyService { 2     protected ReentrantLock lock = new ReentrantLock(true); 3     public void method1(){ 4         try { 5             lock.lock(); 6             System.out.println(Thread.currentThread().getName()+"线程保持lock锁的个数:"+lock.getHoldCount()+" method1"); 7             method2(); 8         } catch (Exception e) { 9             e.printStackTrace();10         } finally {11             lock.unlock();12         }13     }14     15     public void method2(){16         try {17             lock.lock();18             System.out.println(Thread.currentThread().getName()+"线程保持lock锁的个数:"+lock.getHoldCount()+" method2");19         } catch (Exception e) {20             e.printStackTrace();21         } finally {22             lock.unlock();23         }24     }25 }
1 public class ThreadA extends Thread { 2  3     protected MyService myService; 4      5     public ThreadA(MyService myService) { 6         super(); 7         this.myService = myService; 8     } 9 10     public void run() {11         myService.method1();12     }13 14 }
1 public class Test {2     public static void main(String[] args) {3         MyService myService = new MyService();4         new ThreadA(myService).start();5     }6 }

getQueueLength()方法使用

getQueueLength()表示等待获取lock锁的估计线程个数。

1 public class MyService { 2     protected ReentrantLock lock = new ReentrantLock(); 3      4     public void getql(){ 5         System.out.println("等待获取lock锁的估计线程个数:"+lock.getQueueLength()+" method1"); 6     } 7  8     public void synmethod(){ 9         System.out.println(Thread.currentThread().getName()+"开始了。。。");10         lock.lock();11         try {12             Thread.sleep(5000);13         } catch (InterruptedException e) {14             e.printStackTrace();15         }16         lock.unlock();17     }18 }
1 public class ThreadA extends Thread { 2     protected MyService myService; 3      4     public ThreadA(MyService myService) { 5         super(); 6         this.myService = myService; 7     } 8  9     public void run() {10         myService.synmethod();11     }12 }
1 public class Test { 2     public static void main(String[] args) { 3         MyService myService = new MyService(); 4         new ThreadA(myService).start(); 5         new ThreadA(myService).start(); 6         new ThreadA(myService).start(); 7         new ThreadA(myService).start(); 8         new ThreadA(myService).start(); 9         while (true) {10             myService.getql();11             try {12                 Thread.sleep(900);13             } catch (InterruptedException e) {14                 e.printStackTrace();15             }16         }17     }18 }

getWaitQueueLength(condition)的用法

 getWaitQueueLength(condition) 表示返回等待与此锁相关的给定条件condition的线程估计数。比如有3个线程都执行了同一个condition的await方法,那么调用getWaitQueueLength(condition)返回的就是3.

1 public class MyService { 2     protected ReentrantLock lock = new ReentrantLock(); 3     protected Condition condition = lock.newCondition(); 4     protected Condition condition1 = lock.newCondition(); 5      6  7     public void synmethod(){ 8         System.out.println(Thread.currentThread().getName()+"开始了。。。"); 9         lock.lock();10         System.out.println("进入lock锁与condition关联的的估计线程个数:"+lock.getWaitQueueLength(condition));11         System.out.println("进入lock锁与condition1关联的的估计线程个数:"+lock.getWaitQueueLength(condition1));12         System.out.println("");13         try {14             if (!Thread.currentThread().getName().contains("2")) {15                 condition.await();16             }else{17                 condition1.await();18             }19         } catch (InterruptedException e) {20             e.printStackTrace();21         }22         lock.unlock();23     }24 }
1 public class Test { 2     public static void main(String[] args) { 3         MyService myService = new MyService(); 4         new ThreadA(myService).start(); 5         new ThreadA(myService).start(); 6         new ThreadA(myService).start(); 7         new ThreadA(myService).start(); 8         new ThreadA(myService).start(); 9     }10 }

hasQueuedThread(thread)和hasQueuedThreads()的使用

 hasQueuedThread(thread)返回的是线程thread是否在等待获取lock锁

hasQueuedThreads()返回的是是否有线程正在等待获取lock锁

1 public class MyService { 2     protected ReentrantLock lock = new ReentrantLock(); 3     protected Condition condition = lock.newCondition(); 4      5     public void hasa(Thread thread){ 6         if (lock.hasQueuedThread(thread)) { 7             System.out.println(thread.getName()+"正在等待获取lock锁。。。"); 8         }else{ 9             System.out.println(thread.getName()+"不在等待获取lock锁。。。");10         }11         System.out.println("是否有线程在等待获取lock锁:"+lock.hasQueuedThreads());12         System.out.println("");13     }14 15     public void synmethod(){16         System.out.println(Thread.currentThread().getName()+"开始了。。。");17         lock.lock();18         19         if (Thread.currentThread().getName().contains("1")) {20             try {21                 condition.await();22             } catch (InterruptedException e) {23                 e.printStackTrace();24             }25         }26         try {27             Thread.sleep(15000);28         } catch (InterruptedException e) {29             // TODO Auto-generated catch block30             e.printStackTrace();31         }32         lock.unlock();33     }34 }
1 public class Test { 2     public static void main(String[] args) { 3         MyService myService = new MyService(); 4         ThreadA ta = new ThreadA(myService); 5         ta.start(); 6         ThreadA tb = new ThreadA(myService); 7         tb.start(); 8         while (true) { 9             myService.hasa(ta);10             myService.hasa(tb);11             System.out.println(""+ta.getName());12             try {13                 Thread.sleep(1000);14             } catch (InterruptedException e) {15                 e.printStackTrace();16             }17         }18     }19 }

hasWaiters(condition)的用法

hasWaiters(condition)表示是否有线程进入了lock锁与condition相关联的等待中。

1 public class MyService { 2     protected ReentrantLock lock = new ReentrantLock(); 3     protected Condition condition = lock.newCondition(); 4      5     public void synmethod(){ 6         System.out.println(Thread.currentThread().getName()+"开始了。。。"); 7         lock.lock(); 8          9         System.out.println("是否有线程进入了lock锁与condition相关联的等待中:"+lock.hasWaiters(condition));10         if (Thread.currentThread().getName().contains("0")) {11             try {12                 condition.await();13             } catch (InterruptedException e) {14                 e.printStackTrace();15             }16         }17         try {18             Thread.sleep(3000);19         } catch (InterruptedException e) {20             e.printStackTrace();21         }22         lock.unlock();23     }24 }
1 public class Test { 2     public static void main(String[] args) { 3         MyService myService = new MyService(); 4          5         ThreadA ta = new ThreadA(myService); 6         ta.start(); 7          8         try { 9             Thread.sleep(3500);10         } catch (InterruptedException e) {11             e.printStackTrace();12         }13         14         ThreadA tb = new ThreadA(myService);15         tb.start();16         17     }18 }

方法isFair()、isHeldByCurrentThread()、isLocked()的使用

isFair()判断线程锁是不是公平锁

isHeldByCurrentThread()查询当前线程是否保持此锁定

isLocked()查询此锁定是否由任意线程保持

1 public class MyService { 2     protected ReentrantLock lock = new ReentrantLock(true); 3     protected Condition condition = lock.newCondition(); 4      5     public void synmethod(){ 6         System.out.println("lock锁是不是公平锁:"+lock.isFair()); 7         System.out.println("lock锁定是否由任意线程保持:"+lock.isLocked()); 8         System.out.println(Thread.currentThread().getName()+"是否保持lock锁定:"+lock.isHeldByCurrentThread()); 9         lock.lock();10         System.out.println("lock锁定是否由任意线程保持:"+lock.isLocked());11         System.out.println(Thread.currentThread().getName()+"是否保持lock锁定:"+lock.isHeldByCurrentThread());12         lock.unlock();13     }14 }
1 public class Test {2     public static void main(String[] args) {3         MyService myService = new MyService();4         5         ThreadA ta = new ThreadA(myService);6         ta.start();7     }8 }

 

lockInterruptibly()方法的使用

lockInterruptibly()比lock()获取锁之前多了个判断,如果当前线程未被中断,则获取锁定,如果已被中断,则抛出java.lang.InterruptedException异常。

1 public class MyService { 2     protected ReentrantLock lock = new ReentrantLock(true); 3     protected Condition condition = lock.newCondition(); 4      5     public void synmethod(){ 6         try { 7             System.out.println(Thread.currentThread().getName()+" begin "+new Date().toString()); 8             for (int i = 0; i < Integer.MAX_VALUE/20; i++) {
// 大概会延长7 8s,这里不用sleep延长线程时间,而是这样写,是因为调用线程的interrupt()方法时,如果线程在sleep会报异常 9 Math.random();10 }11 if(new Random().nextInt(5)%2==0){
// 随机12 System.out.println(Thread.currentThread().getName()+" 使用的是lock() ");13 lock.lock();14 }else{15 System.out.println(Thread.currentThread().getName()+" 使用的是lockInterruptibly() ");16 lock.lockInterruptibly();17 }18 19 System.out.println(Thread.currentThread().getName()+" lock 1 "+new Date().toString());20 for (int i = 0; i < Integer.MAX_VALUE/20; i++) {
// 同上21 Math.random();22 }23 } catch (InterruptedException e) {24 // TODO Auto-generated catch block25 e.printStackTrace();26 } finally {27 System.out.println(Thread.currentThread().getName()+" lock 2 "+new Date().toString());28 if (lock.isHeldByCurrentThread()) {29 lock.unlock();30 }31 System.out.println(Thread.currentThread().getName()+" end "+new Date().toString());32 }33 }34 }
1 /** 2  * 测试类 3  * @author ko 4  * 5  */ 6 public class Test { 7     public static void main(String[] args) { 8         MyService myService = new MyService(); 9         10         ThreadA taa = new ThreadA(myService);11         taa.setName("taa");12         taa.start();13         14         try {15             Thread.sleep(1500);// 等前面的线程都启动好16         } catch (InterruptedException e) {17             e.printStackTrace();18         }19         20         System.out.println("taa interrupt "+new Date().toString());21         taa.interrupt();// 打标记  这个时候taa还没有进入lock锁里22         23     }24 }

代码里采用了随机的处理,有的时候使用的是lock(),有的时候使用的是lockInterruptibly(),多运行几遍就能得到两种结果。

 

 lock.tryLock()、lock.tryLock(timeout, unit)方法使用

lock.tryLock())  立即返回,获得锁返回true,没获得锁返回false

lock.tryLock(3, TimeUnit.SECONDS) 等待3s,3s后,获得锁返回true,没获得锁返回false

1 public class MyService { 2     protected ReentrantLock lock = new ReentrantLock(true); 3     protected Condition condition = lock.newCondition(); 4      5     public void synmethod(){ 6         try { 7             System.out.println(Thread.currentThread().getName()+"进入方法"+new Date().toString()); 8              9             if (lock.tryLock()) {
// 立即返回,获得锁返回true,没获得锁返回false10 System.out.println(Thread.currentThread().getName()+"获得锁");11 } else {12 System.out.println(Thread.currentThread().getName()+"没有获得锁");13 }14 15 // if (lock.tryLock(3, TimeUnit.SECONDS)) {
// 等待3s,3s后,获得锁返回true,没获得锁返回false16 // System.out.println(Thread.currentThread().getName()+"获得锁的时间"+new Date().toString());17 // Thread.sleep(10000);18 // } else {19 // System.out.println(Thread.currentThread().getName()+"没有获得锁");20 // }21 22 System.out.println(Thread.currentThread().getName()+"方法结束"+new Date().toString());23 } catch (Exception e) {24 e.printStackTrace();25 }26 }27 }
1 /** 2  * 测试类 3  * @author ko 4  * 5  */ 6 public class Test { 7     public static void main(String[] args) { 8         MyService myService = new MyService(); 9         10         ThreadA ta = new ThreadA(myService);11         ta.setName("ta");12         ta.start();13         14         ThreadA taa = new ThreadA(myService);15         taa.setName("taa");16         taa.start();17     }18 }

awaitUninterruptibly()方法使用

当在线程等待的时候,如果外部要中断该线程,不会报InterruptedException异常,而await()会报异常

1 public class MyService { 2     protected ReentrantLock lock = new ReentrantLock(true); 3     protected Condition condition = lock.newCondition(); 4      5     public void synmethod(){ 6         try { 7             System.out.println(Thread.currentThread().getName()+"进入方法"+new Date().toString()); 8  9             lock.lock();10             11             if (new Random().nextInt(5)%2 == 0) {12                 System.out.println(Thread.currentThread().getName()+"走的是await()");13                 condition.await();14             } else {15                 System.out.println(Thread.currentThread().getName()+"走的是awaitUninterruptibly()");16                 condition.awaitUninterruptibly();17             }18             19         } catch (Exception e) {20             e.printStackTrace();21         } finally {22             System.out.println(Thread.currentThread().getName()+"方法结束"+new Date().toString());23             lock.unlock();24         }25     }26 }
1 /** 2  * 测试类 3  * @author ko 4  * 5  */ 6 public class Test { 7     public static void main(String[] args) { 8         MyService myService = new MyService(); 9         10         ThreadA taa = new ThreadA(myService);11         taa.setName("taa");12         taa.start();13         14         try {15             Thread.sleep(1000);16         } catch (InterruptedException e) {17             e.printStackTrace();18         }19         taa.interrupt();// 打标记20     }21 }

awaitUntil(Time time)方法使用

awaitUntil(Time time)和await()一样会使当前线程进入等待状态,不过它有个截止时间,到了time这个时间,自动唤醒。

1 public class MyService { 2     protected ReentrantLock lock = new ReentrantLock(true); 3     protected Condition condition = lock.newCondition(); 4      5     public void synmethod(){ 6         try { 7             System.out.println(Thread.currentThread().getName()+"进入方法"+new Date().toString()); 8  9             lock.lock();10             11             Calendar calendar = Calendar.getInstance();12             calendar.add(Calendar.SECOND, 10);13             System.out.println("begin awaitUntil "+new Date().toString());14             condition.awaitUntil(calendar.getTime());// 15             System.out.println("after awaitUntil "+new Date().toString());16 17         } catch (Exception e) {18             e.printStackTrace();19         } finally {20             System.out.println(Thread.currentThread().getName()+"方法结束"+new Date().toString());21             lock.unlock();22         }23     }24 }
1 /** 2  * 测试类 3  * @author ko 4  * 5  */ 6 public class Test { 7     public static void main(String[] args) { 8         MyService myService = new MyService(); 9         10         ThreadA taa = new ThreadA(myService);11         taa.setName("taa");12         taa.start();13     }14 }

 使用Condition实现顺序执行

1 /** 2  * 利用condition实现顺序执行 3  * @author ko 4  * 5  */ 6 public class MyService implements Runnable{ 7     protected ReentrantLock lock; 8     protected Condition signalCondition;// 在某个线程里负责等待 9     protected Condition awaitCondition;// 在某个线程里负责唤醒10     11     public MyService(ReentrantLock lock, Condition signalCondition, Condition awaitCondition) {12         super();13         this.lock = lock;14         this.signalCondition = signalCondition;15         this.awaitCondition = awaitCondition;16     }17 18     public void print(Condition signalCondition, Condition awaitCondition) throws InterruptedException{19         lock.lock();20         for (int j = 0; j < 10; j++) {21             for (int i = 1; i < 4; i++) {22                 System.out.println(Thread.currentThread().getName()+" "+i);23             }24             System.out.println("");25             signalCondition.signal();26             awaitCondition.await();27         }28         lock.unlock();29     }30 31     public void run() {32         try {33             print(signalCondition, awaitCondition);34         } catch (InterruptedException e) {35             e.printStackTrace();36         }37     }38     39 }
myservice
1 /** 2  * 测试类 3  * @author ko 4  * 5  */ 6 public class Test { 7     public static void main(String[] args) { 8         ReentrantLock lock = new ReentrantLock(); 9         Condition conditionA = lock.newCondition();10         Condition conditionB = lock.newCondition();11         Condition conditionC = lock.newCondition();12         13         MyService myService = new MyService(lock, conditionB, conditionA);14         15         new Thread(new MyService(lock, conditionB, conditionA),"thread a").start();16         new Thread(new MyService(lock, conditionC, conditionB),"thread b").start();17         new Thread(new MyService(lock, conditionA, conditionC),"thread c").start();18 19     }20 }
test
thread a 1thread a 2thread a 3thread b 1thread b 2thread b 3thread c 1thread c 2thread c 3thread a 1thread a 2thread a 3thread b 1thread b 2thread b 3thread c 1thread c 2thread c 3thread a 1thread a 2thread a 3thread b 1thread b 2thread b 3thread c 1thread c 2thread c 3thread a 1thread a 2thread a 3thread b 1thread b 2thread b 3thread c 1thread c 2thread c 3thread a 1thread a 2thread a 3thread b 1thread b 2thread b 3thread c 1thread c 2thread c 3thread a 1thread a 2thread a 3thread b 1thread b 2thread b 3thread c 1thread c 2thread c 3thread a 1thread a 2thread a 3thread b 1thread b 2thread b 3thread c 1thread c 2thread c 3thread a 1thread a 2thread a 3thread b 1thread b 2thread b 3thread c 1thread c 2thread c 3thread a 1thread a 2thread a 3thread b 1thread b 2thread b 3thread c 1thread c 2thread c 3thread a 1thread a 2thread a 3thread b 1thread b 2thread b 3thread c 1thread c 2thread c 3
打印结果

 

转载地址:http://atqto.baihongyu.com/

你可能感兴趣的文章
DotNetBar 6.1 破解
查看>>
ubuntu下登录mysql
查看>>
3.0+百度地图在地图初始化的时候就弹框展示一个信息框,而不是用户点击poi时才弹出...
查看>>
第一部分 mongodb 基础篇
查看>>
emacs之配置4,颜色插件
查看>>
emmet语法
查看>>
[效率提升]工作中的那些命令行
查看>>
citus 多租户应用开发(来自官方文档)
查看>>
java鼠标双击和右键事件处理
查看>>
hash算法
查看>>
聊聊.net程序设计——浅谈使用VS2010建模拓展(上)[转]
查看>>
Archlinux下给T43添加Win键(Super键)
查看>>
Objective-C——消息、Category和Protocol
查看>>
Python 3.x中maketrans和translate用法
查看>>
关于抽象类中构造函数的一些学习
查看>>
CoffeeScript及相关文本标记语言
查看>>
Foundation框架中的NSNumber对象详解
查看>>
Jquery获取下拉选择节点名称值赋给textbox文本框 获取 父节点的栏目名称编号
查看>>
[037] 微信公众帐号开发教程第13篇-图文消息全攻略
查看>>
磁珠的作用
查看>>