String key="product:001";
String key2="product";
for (int i = 0; i <500 ; i++) {
int temp=i;
new Thread(new Runnable() {
@Override
public void run() {
try {
cyclicBarrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
//能用 并发压测(需要加锁) 出现异常(sy会释放持有的锁)
// 单体架构 集群架构(2台服务器怎么保正并发安全-分布锁,sy和re都已经不再适用,因为有多台服务器)
// 宕机
synchronized (o){
Boolean aBoolean = redisTemplate.opsForValue().setIfAbsent(key2, "1",30, TimeUnit.SECONDS);
if (aBoolean){
try{
String s = redisTemplate.opsForValue().get(key);
Integer count = Integer.valueOf(s);
if (count>0){
// TODO: 2019/11/6 业务处理
if (temp%10==0){
int i=1/0;
}
redisTemplate.opsForValue().set("product:001",--count+"");
System.out.println("交易成功"+count);
}else System.out.println("交易失败"+count);
}finally {
redisTemplate.delete(key2);
}
}
}
}
}).start();
在高并发下,通过加锁,让可能出现线程不安全的代码变安全。但是,在单服务器下,sy和re确实能够满足,如果是多台服务器呢?怎么让服务器共享一个对象,达到锁的效果呢?redis提供了简单的分布式锁,setnx这种方法。确实,基于内存的redis是非常适合用来作为服务器之间的通信对象。考虑到项目运行中出现的异常,或者有服务器直接宕机的可能,更需要设置过期时间和finally代码块释放资源,避免死锁。