利用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();
}
}