WEB开发网
开发学院软件开发Java 多线程基础总结九--Mina窥探 阅读

多线程基础总结九--Mina窥探

 2010-01-22 00:00:00 来源:WEB开发网   
核心提示: 使用50个线程每个线程执行500次对counter进行叠加,正确的答案应该是25000,多线程基础总结九--Mina窥探(4),但是很不幸的是仅仅测试几次就出现了24999和其他的小于25000的最大值,所以很遗憾的发现mina的这个变量的方案的选择是有问题的! 这里应该是使用的是AtomicL

使用50个线程每个线程执行500次对counter进行叠加。正确的答案应该是25000,但是很不幸的是仅仅测试几次就出现了24999和其他的小于25000的最大值。所以很遗憾的发现mina的这个变量的方案的选择是有问题的!

这里应该是使用的是AtomicLong,而对应的fireServiceActivated(...)内的代码如果不使用API提供的话应该是:

Java代码

  for (;;) { 
     long current = cumulativeManagedSessionCount.get(); 
     long next = current + 1; 
     if (compareAndSet(current, next)) 
       break; 
  }

虽然是for循环+CAS的atomic杀手锏,但是不要怕,一般for循环cpu都是一次搞定,极少情况是多次,性能不会有什么明显影响。这个 bug可能在数量较少的线程的情况下很难显现,或者是mina的开发者考虑使用情景故意的宽松线程机制?从严谨性来看是我个人认为是不对的。

最后就是看看一个有趣的synchronized的代码片段:

Java代码

  /** 
   * Close all the sessions 
   * TODO disconnectSessions. 
   * 
   */ 
  private void disconnectSessions() { 
    Object lock = new Object(); 
    ... 
    try { 
      synchronized (lock) { 
        while (!managedSessions.isEmpty()) { 
          lock.wait(500); 
        } 
      } 
    } catch (InterruptedException ie) { 
      // Ignored 
    } 
  }

这个方法是关闭所有的会话,但是为了减少线程锁的竞争使用了一个很可爱的方式。这里的lock是个局部变量,所以每个进入这个方法的线程都会拥有一个lock对象,而synchronized(lock)是迷惑的重点。这个synchronized不会使得进入方法的线程们产生任何的竞争,因为每个线程都能获得属于自己的lock。synchronized的作用就在于lock.wait(500)的调用,就因为wait方法必须要 synchronized的配合,所以就出现了这个可爱的代码。这段代码的主要意图就是不管几个线程去关闭所有会话,每个线程都是间隔500ms去检查 managedSessions是否为空。这里没有对managedSessions使用synchronized的原因就是为了减少线程锁对 managedSessions的资源独占,而改用while循环的机制宁愿等待也不为了检查managedSessions而影响其他线程的工作。很精巧的一个实现!

写到这里,算是这个小菜的结尾了,总感觉意犹未尽。mina对高性能并发的目标还是从代码上得到了一些的体现。当然它的高性能主要是对NIO的封装使用,不过这一切都是建立在多线程的并发基础上的。至于之前无意发现的bug(个人认为)如果mina的committer也有相同的认知的话,我想以后会有相应的修改的。

上一页  1 2 3 4 

Tags:线程 基础 总结

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接