知识大全 Java多线程同步-BusyFlag或Lock

Posted

篇首语:奋斗者在汗水汇集的江河里,将事业之舟驶到了理想的彼岸。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 Java多线程同步-BusyFlag或Lock相关的知识,希望对你有一定的参考价值。

Java多线程同步-BusyFlag或Lock  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!

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

    public  class BusyFlag       protected  Thread busyflag =  null;      protected  int busycount =  ;           public  synchronized  void getBusyFlag()           while (tryGetBusyFlag() ==  false)               try                  wait();               catch ( Exception e)                                      private  synchronized  boolean tryGetBusyFlag()           if (busyflag ==  null)              busyflag =  Thread currentThread();             busycount =  ;              return  true;                            if (busyflag ==  Thread currentThread())              busycount++;              return  true;                   return  false;                        public  synchronized  void freeBusyFlag()           if(getOwner()==  Thread currentThread())              busycount ;              if(busycount== )                  busyflag =  null;                                      notify();                                                      public  synchronized  Thread getOwner()           return busyflag;     

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

    import java util Collections; import java util HashMap; import java util Map; class Account       String name;      //float amount;          BusyFlag flag =  new BusyFlag();           //使用一个Map模拟持久存储      static  Map storage =  new  HashMap();      static          storage put( John   new  Float( f));         storage put( Mike   new  Float( f));                static  Map accounts =  Collections synchronizedMap( new  HashMap());                    private Account( String name)           this name = name;          //this amount = ((Float)storage get(name)) floatValue();                public  synchronized  static Account getAccount ( String name)           if (accounts get(name) ==  null)             accounts put(name   new Account(name));          return (Account) accounts get(name);           public  synchronized  void deposit( float amt)           float amount = (( Float)storage get(name)) floatValue();         storage put(name   new  Float(amount + amt));           public  synchronized  void withdraw( float amt)  throws InsufficientBalanceException           float amount = (( Float)storage get(name)) floatValue();          if (amount >= amt)             amount  = amt;          else               throw  new InsufficientBalanceException();                          storage put(name   new  Float(amount));           public  float getBalance()           float amount = (( Float)storage get(name)) floatValue();          return amount;                public  void lock()          flag getBusyFlag();                public  void unlock()          flag freeBusyFlag();     

  新的Account提供了两个用于锁定的方法 lock()和unlock() 供Account对象的客户端在需要时锁定Account和解锁Account Account通过委托给BusyFlag来提供这个机制 另外 大家也发现了 新的Account中提供了对Account对象的缓存 同时去除了public的构造方法 改为使用一个静态工厂方法供用户获取Account的实例 这样做也是有必要的 因为我们希望所有的ATM机同时只能有一个能够对同一个Account进行操作 我们在Account上的锁定是对一个特定Account对象进行加锁 如果多个ATM同时实例化多个同一个user的Account对象 那么仍然可以同时操作同一个账户 所以 要使用这种机制就必须保证Account对象在系统中的唯一性 所以 这儿使用一个Account的缓存 并将Account的构造方法变为私有的 你也可以说 通过在Account类锁上进行同步 即将Account中的BusyFlag对象声明为static的 但这样就使同时只能有一台ATM机进行操作了 这样 在一台ATM机在操作时 全市其它的所有的ATM机都必须等待 另外必须注意的一点是 Account中的getAccount()方法必须同步 否则 将有可能生成多个Account对象 因为可能多个线程同时到达这个方法 并监测到accounts中没有 John 的Account实例 从而实例化多个John的Account实例 sATM类只需作少量改动 在login方法中锁定Account 在logout方法中解锁

    public  class ATM      Account acc;           //作为演示 省略了密码验证      public  synchronized  boolean login( String name)           if (acc !=  null)              throw  new  IllegalArgumentException( Already logged in! );         acc = Account getAccount(name);         acc lock();          return  true;                public  void deposit( float amt)          acc deposit(amt);                public  void withdraw( float amt)  throws InsufficientBalanceException               acc withdraw(amt);                public  float getBalance()           return acc getBalance();                public  synchronized  void logout ()          acc unlock();         acc =  null;          
         Lock l =  ;       l lock();       try            // access the resource protected by this lock        finally           l unlock();      
cha138/Article/program/Java/gj/201311/27585

相关参考

知识大全 Java多线程同步具体实例讲解

Java多线程同步具体实例讲解  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  Java多线程同步

知识大全 浅谈Java多线程的同步问题

浅谈Java多线程的同步问题  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  多线程的同步依靠的是

知识大全 Java多线程共享数据、同步、通信

Java多线程共享数据、同步、通信  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  一线程共享数据

知识大全 java破解ip屏蔽+多线程同步拨号

  单线程破解ip屏蔽比较容易只要拨号就行了  多线程抓取数据也比较容易但是引入多线程之后拨号就容易出现问题  多线程抓取的时候这个拨号就比较麻烦一点因为多线程拨号  会出现第一个线程拨号的时候第二个

知识大全 Java多线程锁如何进行数据同步共享

Java多线程锁如何进行数据同步共享  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  Java多线

知识大全 Java多线程问题之同步器CyclicBarrier

Java多线程问题之同步器CyclicBarrier  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!

知识大全 Java多线程的同步示例及对象锁机制

Java多线程的同步示例及对象锁机制  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!    java

知识大全 Java多线程同步设计中使用Metux

Java多线程同步设计中使用Metux  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  Mutex

知识大全 Java多线程对耗时方法的同步问题

Java多线程对耗时方法的同步问题  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  各位大牛小弟现

知识大全 Java开发中多线程同步技巧[3]

Java开发中多线程同步技巧[3]  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! &nb