久久久久久久视色,久久电影免费精品,中文亚洲欧美乱码在线观看,在线免费播放AV片

<center id="vfaef"><input id="vfaef"><table id="vfaef"></table></input></center>

    <p id="vfaef"><kbd id="vfaef"></kbd></p>

    
    
    <pre id="vfaef"><u id="vfaef"></u></pre>

      <thead id="vfaef"><input id="vfaef"></input></thead>

    1. 站長(zhǎng)資訊網(wǎng)
      最全最豐富的資訊網(wǎng)站

      redis分布式鎖如何實(shí)現(xiàn)原理

      redis分布式鎖如何實(shí)現(xiàn)原理

      分布式鎖,是控制分布式系統(tǒng)之間同步訪問共享資源的一種方式。

      在分布式系統(tǒng)中,常常需要協(xié)調(diào)他們的動(dòng)作。如果不同的系統(tǒng)或是同一個(gè)系統(tǒng)的不同主機(jī)之間共享了一個(gè)或一組資源,那么訪問這些資源的時(shí)候,往往需要互斥來(lái)防止彼此干擾來(lái)保證一致性,在這種情況下,便需要使用到分布式鎖。

      使用setnx、getset、expire、del這4個(gè)redis命令實(shí)現(xiàn) (推薦學(xué)習(xí):Redis視頻教程)

      setnx 是『SET if Not eXists』(如果不存在,則 SET)的簡(jiǎn)寫。 命令格式:SETNX key value;使用:只在鍵 key 不存在的情況下,將鍵 key 的值設(shè)置為 value 。若鍵 key 已經(jīng)存在, 則 SETNX 命令不做任何動(dòng)作。返回值:命令在設(shè)置成功時(shí)返回 1 ,設(shè)置失敗時(shí)返回 0 。

      getset 命令格式:GETSET key value,將鍵 key 的值設(shè)為 value ,并返回鍵 key 在被設(shè)置之前的舊的value。返回值:如果鍵 key 沒有舊值, 也即是說, 鍵 key 在被設(shè)置之前并不存在, 那么命令返回 nil 。當(dāng)鍵 key 存在但不是字符串類型時(shí),命令返回一個(gè)錯(cuò)誤。

      expire 命令格式:EXPIRE key seconds,使用:為給定 key 設(shè)置生存時(shí)間,當(dāng) key 過期時(shí)(生存時(shí)間為 0 ),它會(huì)被自動(dòng)刪除。返回值:設(shè)置成功返回 1 。 當(dāng) key 不存在或者不能為 key 設(shè)置生存時(shí)間時(shí)(比如在低于 2.1.3 版本的 Redis 中你嘗試更新 key 的生存時(shí)間),返回 0 。

      del 命令格式:DEL key [key …],使用:刪除給定的一個(gè)或多個(gè) key ,不存在的 key 會(huì)被忽略。返回值:被刪除 key 的數(shù)量。

      Redis實(shí)現(xiàn)分布式鎖的原理:

      1.通過setnx(lock_timeout)實(shí)現(xiàn),如果設(shè)置了鎖返回1, 已經(jīng)有值沒有設(shè)置成功返回0

      2.死鎖問題:通過實(shí)踐來(lái)判斷是否過期,如果已經(jīng)過期,獲取到過期時(shí)間get(lockKey),然后getset(lock_timeout)判斷是否和get相同,相同則證明已經(jīng)加鎖成功,因?yàn)榭赡軐?dǎo)致多線程同時(shí)執(zhí)行g(shù)etset(lock_timeout)方法,這可能導(dǎo)致多線程都只需getset后,對(duì)于判斷加鎖成功的線程, 再加expire(lockKey, LOCK_TIMEOUT, TimeUnit.MILLISECONDS)過期時(shí)間,防止多個(gè)線程同時(shí)疊加時(shí)間,導(dǎo)致鎖時(shí)效時(shí)間翻倍

      redis分布式鎖如何實(shí)現(xiàn)原理代碼:

      /**  * @author yaoxin  * @date 2018/8/13下午5:04  */ public class RedisLockTest {       public static final String url = "jdbc:mysql://127.0.0.1:3306/ly?characterEncoding=UTF-8";     public static final String name = "com.mysql.jdbc.Driver";     public static final String user = "root";     public static final String password = "";       public static void main(String[] args) {           Integer count = 50;         while (count > 0) {             count--;             new Thread(new Runnable() {                 @Override                 public void run() {                     Jedis jedis = new Jedis("127.0.0.1", 6379);                     jedis.auth("1234");                     String lock = lock(jedis);                     if (lock != null) {                         Statement statement = null;                         Connection conn = null;                         ResultSet resultSet = null;                         try {                             Class.forName(name);// 指定連接類型                             conn = DriverManager.getConnection(url, user, password);// 獲取連接                             statement = conn.createStatement();// 準(zhǔn)備執(zhí)行語(yǔ)句                             String querySql = "SELECT id,name,count FROM production WHERE id=2";                             resultSet = statement.executeQuery(querySql);                             int count = 0;                             while (resultSet.next()) {                                 System.out.println(Thread.currentThread().getName() + "搶到了鎖 id: " + resultSet.getString("id")                                         + " name: " + resultSet.getString("name")                                         + " count: " + resultSet.getString("count"));                                 count = Integer.valueOf(resultSet.getString("count"));                             }                             String updateSql = "UPDATE production SET count=" + (count - 1)                                     + " WHERE id=2";                             int rows = statement.executeUpdate(updateSql);                             if (rows > 0) {                                 System.out.println("更新成功" + Thread.currentThread().getName() + "  庫(kù)存剩余:" + (count - 1));                                 System.out.println(Thread.currentThread().getName() + " === > >開始解鎖");                                 boolean unlock = unlock(jedis, lock);                                 if (unlock)                                     System.out.println(Thread.currentThread().getName() + " === > >解鎖成功");                             } else {                                 System.out.println("更新失敗" + Thread.currentThread().getName());                             }                         } catch (Exception e) {                             e.printStackTrace();                         } finally {                             try {                                 if (conn != null)                                     conn.close();                                 if (statement != null)                                     statement.close();                                 if (resultSet != null)                                     resultSet.close();                             } catch (Exception e) {                                 e.printStackTrace();                             }                         }                     }                 }             }, "線程" + count).start();         }     }       public static String lock(Jedis jedis) {         try {             while (true) {                 String lockTime = Long.valueOf(jedis.time().get(0)) + 5 + "";                 if (jedis.setnx("lock", lockTime) == 1) {                     jedis.expire("lock", 5);                     return lockTime;                 }                 String lock = jedis.get("lock");                 if (!StringUtils.isEmpty(lock) && Long.valueOf(lock) < Long.valueOf(jedis.time().get(0))) {                     String oldLockTime = jedis.getSet("lock", lockTime);                     if (!StringUtils.isEmpty(oldLockTime) && oldLockTime.equals(lock)) {                         return lockTime;                     }                 }                 Thread.sleep(100);             }         } catch (Exception e) {             e.printStackTrace();         }         return null;     }       public static boolean unlock(Jedis jedis, String lockTag) {         if (lockTag.equals(jedis.get("lock"))) {             jedis.del("lock");             return true;         }         return false;     }   }

      運(yùn)行結(jié)果如下圖:

      redis分布式鎖如何實(shí)現(xiàn)原理

      贊(0)
      分享到: 更多 (0)
      網(wǎng)站地圖   滬ICP備18035694號(hào)-2    滬公網(wǎng)安備31011702889846號(hào)