zoukankan      html  css  js  c++  java
  • 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加锁==============================================

     

     

  • 相关阅读:
    3164 质因数分解
    codevs3249搭积木
    codevs 2964公共素数因数
    爱改名的小融1
    单链表基础练习
    并查集(union-find sets)
    string类中字符的大小写转换
    蒜头君学英语--set()练习
    打印锯齿矩阵
    堆积木
  • 原文地址:https://www.cnblogs.com/beyang/p/8384472.html
Copyright © 2011-2022 走看看