我知道servlet不是线程安全的,如果在servlet中定义了成员变量,在多线程环境中,可能就会出现问题。比如我想做个页面访问量的计数器,定义了一个成员变量count,每次访问就在doGet方法中加1,那么该如何做才能保证它的计数是准确的呢?除了加锁之外。上次面试就被问了这个问题。
如果count是Servlet成员变量,那么需要用synchronized来同步。
synchronized(this) {
count++;
}
线程安全问题可以参考我写的一篇博客:http://xxgblog.com/2013/05/16/java-thread-safe/
把count加在application上面
使用原子类,比如AtomicInteger
或者AtomicLong
import java.util.concurrent.atomic.AtomicInteger;
public class AtomicIntegerExample {
private static AtomicInteger at = new AtomicInteger(0);
static class MyRunnable implements Runnable {
private int myCounter;
private int myPrevCounter;
private int myCounterPlusFive;
private boolean isNine;
public void run() {
myCounter = at.incrementAndGet();
System.out.println("Thread " + Thread.currentThread().getId() + " / Counter : " + myCounter);
myPrevCounter = at.getAndIncrement();
System.out.println("Thread " + Thread.currentThread().getId() + " / Previous : " + myPrevCounter);
myCounterPlusFive = at.addAndGet(5);
System.out.println("Thread " + Thread.currentThread().getId() + " / plus five : " + myCounterPlusFive);
isNine = at.compareAndSet(9, 3);
if (isNine) {
System.out.println("Thread " + Thread.currentThread().getId()
+ " / Value was equal to 9, so it was updated to " + at.intValue());
}
}
}
public static void main(String[] args) {
Thread t1 = new Thread(new MyRunnable());
Thread t2 = new Thread(new MyRunnable());
t1.start();
t2.start();
}
}
参考:Java AtomicInteger Example