2014-04-27 20:16
题目:假设一个类Foo有三个公有的成员方法first()、second()、third()。请用锁的方法来控制调用行为,使得他们的执行循序总是遵从first、second、third的顺序。
解法:你应该想到了用lock的方法类阻塞,不过这里面有个概念问题使得直接用ReentrantLock不能通过编译(对于一个锁对象,不同在A线程中锁定,又在B线程中解锁,不允许这样的归属关系),可以用Semaphore来达到相同的目的。请看下面的代码。
代码:
1 // 16.5 There're three methods in a class FooBar, how would you make sure that they're executed in a fixed order, in whichever order they're called? 2 public class FirstRun implements Runnable { 3 private FooBar fooBar; 4 5 public FirstRun(FooBar fooBar) { 6 // TODO Auto-generated constructor stub 7 this.fooBar = fooBar; 8 } 9 10 @Override 11 public void run() { 12 // TODO Auto-generated method stub 13 fooBar.first(); 14 } 15 } 16 17 // ----------------------------------------------------------------------------- 18 public class SecondRun implements Runnable { 19 private FooBar fooBar; 20 21 public SecondRun(FooBar fooBar) { 22 // TODO Auto-generated constructor stub 23 this.fooBar = fooBar; 24 } 25 26 @Override 27 public void run() { 28 // TODO Auto-generated method stub 29 fooBar.second(); 30 } 31 } 32 33 // ----------------------------------------------------------------------------- 34 public class ThirdRun implements Runnable { 35 private FooBar fooBar; 36 37 public ThirdRun(FooBar fooBar) { 38 // TODO Auto-generated constructor stub 39 this.fooBar = fooBar; 40 } 41 42 @Override 43 public void run() { 44 // TODO Auto-generated method stub 45 fooBar.third(); 46 } 47 } 48 49 // ----------------------------------------------------------------------------- 50 import java.util.concurrent.Semaphore; 51 52 public class FooBar { 53 private Semaphore sem1; 54 private Semaphore sem2; 55 private Semaphore sem3; 56 57 public FooBar() { 58 // TODO Auto-generated constructor stub 59 sem1 = new Semaphore(1); 60 sem2 = new Semaphore(1); 61 sem3 = new Semaphore(1); 62 63 try { 64 sem1.acquire(); 65 sem2.acquire(); 66 sem3.acquire(); 67 } catch (InterruptedException e) { 68 // TODO Auto-generated catch block 69 e.printStackTrace(); 70 } 71 } 72 73 public void first() { 74 System.out.println("first"); 75 76 sem1.release(); 77 } 78 79 public void second() { 80 try { 81 sem1.acquire(); 82 } catch (InterruptedException e) { 83 // TODO Auto-generated catch block 84 e.printStackTrace(); 85 } 86 sem1.release(); 87 System.out.println("second"); 88 sem2.release(); 89 } 90 91 public void third() { 92 try { 93 sem2.acquire(); 94 } catch (InterruptedException e) { 95 // TODO Auto-generated catch block 96 e.printStackTrace(); 97 } 98 sem2.release(); 99 System.out.println("third"); 100 sem3.release(); 101 } 102 103 public static void main(String[] args) { 104 FooBar fooBar = new FooBar(); 105 Thread t1 = new Thread(new FirstRun(fooBar)); 106 Thread t2 = new Thread(new SecondRun(fooBar)); 107 Thread t3 = new Thread(new ThirdRun(fooBar)); 108 109 t3.start(); 110 t1.start(); 111 t2.start(); 112 } 113 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)