多线程基础总结九--Mina窥探
2010-01-22 00:00:00 来源:WEB开发网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;
}
}
更多精彩
赞助商链接