redis分布式锁

1. 在多线程并发的场景下,使用锁来控制多个任务对同一共享资源的访问,拿到锁的任务优先访问公共资源

//并发的用户数

private static final int threadNum = 10;

//倒计数器(发令抢),用于制造线程的并发执行

private static CountDownLatch cdl = new CountDownLatch(threadNum);

public void run(){

  try{

    cdl.await();//线程运行到这里等待,等待发令枪计数器变为0

  }catch(InterruptedException e){

    e.printStackTrace();

  }

  //线程结束后,所有线程同时执行换行给printer 发送打印指令

  Printer.print(Thread.currentThread().getName()+"");

}

public static void main(String[] args){

  for(int i=0;i<threadNum;i++){

    new Thread(new PrintTask("sssssss")).start();

    cdl.countDown();

  }

}

///以上存在线程安全问题:

1. 使用 synchronized

public void run(){

  try{

    cdl.await();//线程运行到这里等待,等待发令枪计数器变为0

  }catch(InterruptedException e){

    e.printStackTrace();

  }
  //同步
    synchronized(cdl){
  Printer.print(Thread.currentThread().getName()+"");
   }  
}

 2. 线程加锁

private Lock lock=new ReentrantLock();
public void run(){   try{     cdl.await();//线程运行到这里等待,等待发令枪计数器变为0   }catch(InterruptedException e){     e.printStackTrace();   }   //   lock.lock();
  try{
    Printer.print(Thread.currentThread().getName()+""); }catch(Exception e){
    
  }finally{
    lock.unlock();
  } }

redis分布式锁

public class RedisLock implements Lock{

  private static final String LOCK_KEY="lock";

  private ThreadLocal<String> local=new ThreadLocal<String>();//线程传值

  //阻塞时锁

  public void lock(){

    if(tryLock()){

      return;

    }else{

      Thread.sleep(200);  //使用trycatch包围

      lock();

    }

  }

  //非阻塞锁

  public boolean tryLock(){

    String uuid=UUID.randomUUID().toString();

    Jedis redis=new Jedis("localhost");

    String ret = redis.set(LOCK_KEY,uuid,"NX","PX",100);

    if(ret!=null&&ret.equals("OK")){

      local.set(uuid);

      return true;

    }

    return false;

  }

  //解锁

  public void unlock(){

    String script=FileUtils.readFileByLines("lua脚本文件地址");  //读取lua脚本文件

    Jedis redis=new Jedis("localhost");

    List<String> keys=new ArrayList<String>();

    keys.add(LOCK_KEY);

    List<String> args=new ArrayList<String>();

    keys.add(local.get());//get  uuid

    redis.eval(script,keys,args);

  }

}

lua脚本

if redis.call("get",KEYS[1])==ARGV[1] then

  return redis.call("del",KEYS[1])

else

  return 0

end 

 ========================redis加锁==============================================

 

 

原文地址:https://www.cnblogs.com/beyang/p/8384472.html