public class Demo1 {
//总访问量
static int count=0;
/*
* 耗时太长的原因是什么呢?
* 程序中的request 方法使用synchronized,关键字修饰,保证了并发的情况下,
* request同一时间只允许一个进程进入
* Q:如何解决耗时长的问题?
* A:count++ 操作实际上是由3步来完成:(jvm执行引擎)
* 1.获取count的值,记作A:A=count
* 2.将 A值+1,得到B:B=A+1;
* 3.将B值赋值给count
* 升级第三步的实现:
* 1.获取锁
* 2.获取count最新的值,记作LV
* 3.判断LV是否等于A如果相等,则将B的值赋值给count 并返回true ,否则返回false
* 4.释放锁
*/
//模拟访问的方法
public synchronized static void request() throws InterruptedException {
Thread.sleep(5);
count++;
}
public static void main(String[] args) throws InterruptedException{
//开始时间
long startTime = System.currentTimeMillis();
//定义线程数
int threadSize=100;
final CountDownLatch countDownLatch=new CountDownLatch(threadSize);
for (int i = 0; i <threadSize ; i++) {
new Thread(new Runnable() {
@Override
public void run() {
//模拟用户访问每个用户访问10次
try {
for (int j = 0; j < 10; j++) {
request();
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
countDownLatch.countDown();
}
}
}).start();
}
countDownLatch.await();
long endTime = System.currentTimeMillis();
System.out.println(Thread.currentThread().getName()+",耗时:"+(endTime-startTime)+",count="+count);
}
}
CAS
全称=“CompareAndSwap”,中文翻译过来为“比较并替换”
怎么使用JDK提供的CAS支持?
A:java 提供了对CAS操作的支持 。具体在sun.misc.unsafe类中
public final native boolean compareAndSwapObject(Object var1,long var2,Object var4 ,Object var5)
public final native boolean compareAndSwapInt(Object var1,long var2,Int var4 ,Int var5)
public final native boolean compareAndSwapLong(Object var1,long var2,long var4 ,long var5)
参数var1:表示要操作的对象
参数var2:表示要操作对象中属性地址的偏移量
参数var4:表示需要修改数据的期望的值
参数var5:表示需要修改为的新值
CAS实现原理是什么?
CAS通过调用JNI的代码实现。JNI:java Native Interface,允许java调用其它语言,而compareAndSwapxx系列的方法就是借助 “c ”语言来调用cpu底层指令实现的。
以常用的Intelx86 平台来说,最终映射到cpu 的指令为“cmpxchg”这是一个原子指令,cpu执行此命令,实现比较并替换的操作
现代计算机动不动就上百 核心 ,cmpxchg,怎么保证多核心下的线程安全?
系统底层进行CAS操作的时候,会判断当前系统是否为多核心系统,如果是就给“总线”加锁。只有一个线程会对总线加锁成功,加锁成功之后会执行cas操作,也就是说CAS的原子性是平台级别的!
CAS问题?
ABA问题?
如何解决?
AtomicStampedReference<T>
方法:
compareAndSet(expectReference,newReference,expectStamp,newStamp)