欢迎访问悦橙教程(wld5.com),关注java教程。悦橙教程  java问答|  每日更新
页面导航 : > > 文章正文

如何改善Java中锁的性能(1)(2)

来源: javaer 分享于  点击 37022 次 点评:39

缩小锁的作用范围

现在,当确信了需要保护的是数据而非程序后,我们应该确保我们只在必要的地方加锁——例如当上面的代码被重构之后:

  1. public class GameServer { 
  2.  
  3. public Map> tables = new HashMap>(); 
  4.  
  5. public void join(Player player, Table table) { 
  6.  
  7. if (player.getAccountBalance() > table.getLimit()) { 
  8.  
  9. synchronized (tables) { 
  10.  
  11. List tablePlayers = tables.get(table.getId()); 
  12.  
  13. if (tablePlayers.size() < 9) { 
  14.  
  15. tablePlayers.add(player); 
  16.  
  17.  
  18.  
  19.  
  20.  
  21. //other methods skipped for brevity 
  22.  

这样那段包含对玩家账号余额检测(可能引发IO操作)的可能引起费时操作的代码,被移到了锁控制的范围之外。注意,现在锁仅仅被用来防止玩家人数超过桌子可容纳的人数,对账户余额的检查不再是该保护措施的一部分了。

分离锁

你可以从上面例子最后一行代码清楚的看到:整个数据结构是由相同的锁保护着。考虑到在这一种数据结构中可能会有数以千计的牌桌,而我们必须保护任何一张牌桌的人数不超过容量,在这样的情况下仍然会有很高的风险出现竞争事件。

关于这个有一个简单的办法,就是对每一张牌桌引入分离锁,如下面这个例子所示:

  1. public class GameServer { 
  2.  
  3. public Map> tables = new HashMap>(); 
  4.  
  5. public void join(Player player, Table table) { 
  6.  
  7. if (player.getAccountBalance() > table.getLimit()) { 
  8.  
  9. List tablePlayers = tables.get(table.getId()); 
  10.  
  11. synchronized (tablePlayers) { 
  12.  
  13. if (tablePlayers.size() < 9) { 
  14.  
  15. tablePlayers.add(player); 
  16.  
  17.  
  18.  
  19.  
  20.  
  21. //other methods skipped for brevity 
  22.  

现在,我们只对单一牌桌的可访问性进行同步而不是所有的牌桌,这样就显著降低了出现锁竞争的可能性。举一个具体的例子,现在在我们的数据结构中有100个牌桌的实例,那么现在发生竞争的可能性就会比之前小100倍。




相关栏目:

用户点评