最近有一个竞拍的项目会用到分布式锁,网上查到的结果是有三种途径可以实现。1.数据库锁机制,2.redis的锁,3.zookeeper。考虑到使用mysql实现会在性能这一块会受影响,zookeeper又是不怎么会。所以使用redis来实现了。


第一种:使用redis的watch命令进行实现


如上图所示:session1在执行修改之前使用watch命令监视了age,然后又在session2更新了age之后,session1在执行exec,在该命令执行的时候应该会检查age值是否更改,现在是已经发生了改变,所以返回执行失败。

基于上述图示写了一段java代码

复制代码
import redis.clients.jedis.Jedis; import redis.clients.jedis.Transaction;  import java.util.List;   public class RedisWatchTest extends  Thread {      private String auctionCode;     public RedisWatchTest (String auctionCode) {         super(auctionCode);         this.auctionCode = auctionCode;     }     private static int bidPrice = 100;      public static void main(String[] args) {         System.out.println(Thread.currentThread().getName() + "主线程运行开始!");         //更改key为a的值        Jedis jedis=new Jedis("127.0.0.1",6379);         jedis.set("goodsprice","0");         System.out.println("输出初始化值:"+jedis.get("goodsprice"));         jedis.close();         RedisWatchTest thread1 = new RedisWatchTest("A001");         RedisWatchTest thread2  = new RedisWatchTest("B001");         thread1.start();         thread2.start();         try{             thread1.join();             thread2.join();        }catch(InterruptedException e){            e.printStackTrace();        }         System.out.println(Thread.currentThread().getName() + "主线程运行结束!");     }      @Override     public void run() {         System.out.println(Thread.currentThread().getName() + "线程运行开始 ");         Jedis jedis=new Jedis("127.0.0.1",6379);         try {             if(Thread.currentThread().getName()=="B001"){                 sleep(1000);             }         } catch (InterruptedException e) {             e.printStackTrace();         }         //监视KEY        jedis.watch("goodsprice");         //A先进        String v =  jedis.get("goodsprice");         Integer iv = Integer.valueOf(v);         //条件都给过        if(bidPrice > iv){             Transaction tx = jedis.multi();// 开启事务            Integer bp = iv + 100;             //出价成功,事务未提交            tx.set("goodsprice",String.valueOf(bp));             System.out.println("子线程" + auctionCode + "set成功");             try {                 if(Thread.currentThread().getName()=="A001"){                     sleep(2000);                 }             } catch (InterruptedException e) {                 e.printStackTrace();             }             List<Object> list = tx.exec();             if (list == null ||list.size()==0) {                 System.out.println("子线程" + auctionCode + ",出价失败");             }else{                 System.out.println("子线程"+this.auctionCode +", 出价:"+ jedis.get("goodsprice") +",出价时间:"
+ System.nanoTime()); } }else{ System.out.println("出价低于现有价格!"); } jedis.close(); System.out.println(Thread.currentThread().getName() + "线程运行结束"); } }
复制代码

执行结果:
main主线程运行开始!
输出初始化值:0
B001线程运行开始 
A001线程运行开始