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

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

 2010-01-22 00:00:00 来源:WEB开发网   
核心提示: Java代码 fireServiceActivated(){if(!activated.compareAndSet(false,true)){//Theinstanceisalreadyactivereturn;}...}这里可以看到activated的状态改变是要依赖其原来的值得,也就是如果使

Java代码

fireServiceActivated() { 
    if (!activated.compareAndSet(false, true)) { 
      // The instance is already active 
      return; 
    } 
    ... 
}

这里可以看到activated的状态改变是要依赖其原来的值得,也就是如果使用volatile的话,要判断之前的是否为false,不满足则置为true。这样的操作对于volatile只能使用锁同步实现。而AtomicBoolean的“CAS”轻松的使用无锁同步原语解决了这个问题。 compareAndSet(...)不管有多少个线程执行,只有取得activated最新值得线程才能返回true,其余的都会是false。这就看到mina的committer还是很纠结性能的。

然后看看那几个volatile的变量吧。首先是activationTime,这个变量除了有自身的get()可以随时取得最新的值之外,就在 fireServiceActivated()内出现了:activationTime = System.currentTimeMillis();可以看到仅仅是一次性的赋值而且不依赖其自身的值。所以完全的满足线程安全的条件。 largestManagedSessionCount的使用和其类似。

再来看看cumulativeManagedSessionCount,它是一个全局的计数器,负责记录启动后所管理得会话数量。除了同样有get()方法之外就是出现在fireSessionCreated(...)方法中:cumulativeManagedSessionCount ++;这引起了我的注意,因为这样的写法是不能保证线程同步的!因为volatile的变量根本无法完成“++”的原子操作。“++”是需要依赖其自身的值而进行更改的操作。为此我简单的写了个验证的例子证明了这个铁律。

Java代码

/** 
 * 
 * @author: yanxuxin 
 * @date: 2010-1-16 
 */ 
public class VolatileTest { 
 
 public static void main(String[] args) { 
 final VolatileSample sample = new VolatileSample(); 
  
 Runnable runnable = new Runnable() { 
  public void run() { 
  for(int i = 0; i < 500; i++) { 
   System.out.println(sample.incrementAndGet()); 
  } 
  } 
 }; 
  
 for(int i = 0; i < 50; i++) { 
  new Thread(runnable).start(); 
 } 
 } 
} 
 
class VolatileSample { 
 private volatile long counter = 0; 
 
 public long incrementAndGet() { 
 counter++; 
 return get(); 
 } 
 
 public long get() { 
 return counter; 
 } 
}

上一页  1 2 3 4  下一页

Tags:线程 基础 总结

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