利用cas算法实现。基于乐观锁。如果值发生冲突。加入异步线程递归进行抢(设置递归次数。防止死循环)
1、创建ThreadUtils类
/**
* 线程副本,保证数据
*/
public class ThreadUtils {
private static ThreadLocal<Integer> threadLocal;
static{
threadLocal = new ThreadLocal();
}
public static void set(int value){
threadLocal.set(value);
}
public static Integer get(){
return threadLocal.get();
}
}
2、创建CasUtils类
/**
* 基于cas原理实现高并发
*/
public class CasUtils implements Runnable{
/**
* 私有内部类创建单例
*/
private static class AtomicHolder{
private static volatile AtomicInteger s = new AtomicInteger(ThreadUtils.get());
}
/**
* 线程池
*/
private static ThreadPoolExecutor ex;
static {
ex = new ThreadPoolExecutor(
10,10,5,TimeUnit.SECONDS,
new ArrayBlockingQueue<Runnable>(1),
new ThreadPoolExecutor.DiscardOldestPolicy());
}
public CasUtils()throws Exception{
int value = ThreadUtils.get();
if(!AtomicHolder.s.compareAndSet(value,value)){
/**
* 此处对于未赋值的进行其他操作
*/
}
}
@Override
public void run() {
System.out.println("我在抢票中..."+Thread.currentThread());
try {
int value = AtomicHolder.s.get();
int si = 0;
if(value-1>=0&&(si=AtomicHolder.s.decrementAndGet())>0){
/**
* 涉及业务可以写入消息队列
*/
System.out.println("抢票成功..."+Thread.currentThread()+"========"+(si));
}else{
/*if(value-1<0){
System.out.println("暂无票..."+Thread.currentThread()+"========"+(si));
return;
}*/
ex.execute(new Runnable() {
@Override
public void run() {
System.out.println("抢票循环..."+Thread.currentThread());
boolean isSubmit = true;
//设置抢票循环次数。
int time = 0;
while(isSubmit){
++time;
int value = AtomicHolder.s.get();
//超过10次结束
if(time>=10){
System.out.println("抢票结束【未抢到】..."+Thread.currentThread());
isSubmit = false;
break;
}
if(value-1>=0&&AtomicHolder.s.decrementAndGet()>0){
/**
* 涉及业务可以写入消息队列
*/
isSubmit = false;
System.out.println("抢票成功..."+Thread.currentThread());
}
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
}
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
3、执行
public static void main(String[] args) throws Exception {
for(int i=0;i<100;i++){
ThreadUtils.set(10);
new Thread( new CasUtils()).start();
}
}