Java多线程同步教程--BusyFlag或Lock (下)

2014-11-23 23:19:11 · 作者: · 浏览: 0
请首先阅读上篇:
Java多线程同步教程--BusyFlag或Lock (上)

我们首先开发一个BusyFlag的类,类似于C++中的Simaphore。

  1. public class BusyFlag {
  2. protected Thread busyflag = null;
  3. protected int busycount = 0;
  4. public synchronized void getBusyFlag() {
  5. while (tryGetBusyFlag() == false) {
  6. try {
  7. wait();
  8. } catch (Exception e) {}
  9. }
  10. }
  11. private synchronized boolean tryGetBusyFlag() {
  12. if (busyflag == null) {
  13. busyflag = Thread.currentThread();
  14. busycount = 1;
  15. return true;
  16. }
  17. if (busyflag == Thread.currentThread()) {
  18. busycount++;
  19. return true;
  20. }
  21. return false;
  22. }
  23. public synchronized void freeBusyFlag() {
  24. if(getOwner()== Thread.currentThread()) {
  25. busycount--;
  26. if(busycount==0) {
  27. busyflag = null;
  28. notify();
  29. }
  30. }
  31. }
  32. public synchronized Thread getOwner() {
  33. return busyflag;
  34. }
  35. }

注:参考Scott Oaks & Henry Wong《Java Thread》

BusyFlag有3个公开方法:getBusyFlag, freeBusyFlag, getOwner,分别用于获取忙标志、释放忙标志和获取当前占用忙标志的线程。使用这个BusyFlag也非常地简单,只需要在需要锁定的地方,调用BusyFlag的getBusyFlag(),在对锁定的资源使用完毕时,再调用改BusyFlag的freeBusyFlag()即可。下面我们开始改造上篇中的Account和ATM类,并应用BusyFlag工具类使得同时只有一个线程能够访问同一个账户的目标得以实现。首先,要改造Account类,在Account中内置了一个BusyFlag对象,并通过此标志对象对Account进行锁定和解锁:

  1. import java.util.Collections;
  2. import java.util.HashMap;
  3. import java.util.Map;
  4. class Account {
  5. String name;
  6. //float amount;
  7. BusyFlag flag = new BusyFlag();
  8. //使用一个Map模拟持久存储
  9. static Map storage = new HashMap();
  10. static {
  11. storage.put("John", new Float(1000.0