国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

DCS實踐干貨:使用Redis實現分布式鎖

xiguadada / 1324人閱讀

摘要:如果應用服務集群部署,則涉及到對分布式應用加鎖。當前分布式加鎖主要有三種方式磁盤數據庫緩存數據庫。以上代碼實現僅展示使用服務進行加鎖訪問的便捷性,具體技術實現需要考慮死鎖鎖的檢查等情況,歡迎點擊分布式緩存服務了解更多。

場景介紹
很多互聯網場景(如商品秒殺,論壇回帖蓋樓等),需要用加鎖的方式,以對某種資源進行順序訪問控制。如果應用服務集群部署,則涉及到對分布式應用加鎖。當前分布式加鎖主要有三種方式:(磁盤)數據庫、緩存數據庫、Zookeeper。接下里讓我們一起看看加鎖實踐過程。

加鎖實現
package dcsDemo01;
import java.util.UUID;
import redis.clients.jedis.Jedis;
public class DistributedLock {

private final String host = "192.168.0.220";
private final int port = 6379;
private static final String SUCCESS = "OK";
private static final String SET_IF_NOT_EXIST = "NX";
private static final String EXPIRE_TIME = "PX";
public  DistributedLock(){}
/*
 * @param lockName      鎖名
 * @param timeout       獲取鎖的超時時間
 * @param lockTimeout   鎖的有效時間
 * @return              鎖的標識
 */
public String getLockWithTimeout(String lockName, long timeout, long lockTimeout) {
    String ret = null;
    Jedis jedisClient = new Jedis(host, port);
    try {
        String authMsg = jedisClient.auth("Demo@123");
        if (!SUCCESS.equals(authMsg)) {
            System.out.println("AUTH FAILED: " + authMsg);
        }

        String identifier = UUID.randomUUID().toString();
        String lockKey = "DLock:" + lockName;
        long end = System.currentTimeMillis() + timeout;

        while(System.currentTimeMillis() < end) {
            String result = jedisClient.set(lockKey, identifier, SET_IF_NOT_EXIST, EXPIRE_TIME, lockTimeout);
            if(SUCCESS.equals(result)) {
                ret = identifier;
                break;
            }

            try {
                Thread.sleep(2);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
    }
    catch (Exception e) {
        e.printStackTrace();
    }finally {
        jedisClient.quit();
        jedisClient.close();
    }

    return ret;
}

/*
 * @param lockName        鎖名
 * @param identifier    鎖的標識
 */
public void releaseLock(String lockName, String identifier) {
    Jedis jedisClient = new Jedis(host, port);

    try {
        String authMsg = jedisClient.auth("Demo@123");
        if (!SUCCESS.equals(authMsg)) {
            System.out.println("AUTH FAILED: " + authMsg);
        }

        String lockKey = "DLock:" + lockName;
        if(identifier.equals(jedisClient.get(lockKey))) {
            jedisClient.del(lockKey);
        }
    }
    catch (Exception e) {
        e.printStackTrace();
    }finally {
        jedisClient.quit();
        jedisClient.close();
    }
}

}

測試代碼
假設20個線程對10臺mate10手機進行搶購:
package dcsDemo01;
import java.util.UUID;

public class CaseTest {

public static void main(String[] args) {
    ServiceOrder service = new ServiceOrder();
    for (int i = 0; i < 20; i++) {
        ThreadBuy client = new ThreadBuy(service);
        client.start();
    }
}

}

class ServiceOrder {

private final int MAX = 10;

DistributedLock DLock = new DistributedLock();

int n = 10;

public void handleOder() {
    String userName = UUID.randomUUID().toString().substring(0,8) + Thread.currentThread().getName();
    String identifier = DLock.getLockWithTimeout("Huawei Mate 10", 10000, 2000);
    System.out.println("正在為用戶:" + userName + " 處理訂單");
    if(n > 0) {
        int num = MAX - n + 1;
        System.out.println("用戶:"+ userName + "購買第" + num + "臺,剩余" + (--n) + "臺");
    }else {
        System.out.println("用戶:"+ userName + "無法購買,已售罄!");
    }
    DLock.releaseLock("Huawei Mate 10", identifier);
}

}

class ThreadBuy extends Thread {

private ServiceOrder service;

public ThreadBuy(ServiceOrder service) {
    this.service = service;
}

@Override
public void run() {
    service.handleOder();
}

}

運行結果
配置好實際的緩存實例連接地址、端口與連接密碼,運行代碼,得到以下結果:
正在為用戶:eee56fb7Thread-16 處理訂單
用戶:eee56fb7Thread-16購買第1臺,剩余9臺
正在為用戶:d6521816Thread-2 處理訂單
用戶:d6521816Thread-2購買第2臺,剩余8臺
正在為用戶:d7b3b983Thread-19 處理訂單
用戶:d7b3b983Thread-19購買第3臺,剩余7臺
正在為用戶:36a6b97aThread-15 處理訂單
用戶:36a6b97aThread-15購買第4臺,剩余6臺
正在為用戶:9a973456Thread-1 處理訂單
用戶:9a973456Thread-1購買第5臺,剩余5臺
正在為用戶:03f1de9aThread-14 處理訂單
用戶:03f1de9aThread-14購買第6臺,剩余4臺
正在為用戶:2c315ee6Thread-11 處理訂單
用戶:2c315ee6Thread-11購買第7臺,剩余3臺
正在為用戶:2b03b7c0Thread-12 處理訂單
用戶:2b03b7c0Thread-12購買第8臺,剩余2臺
正在為用戶:75f25749Thread-0 處理訂單
用戶:75f25749Thread-0購買第9臺,剩余1臺
正在為用戶:26c71db5Thread-18 處理訂單
用戶:26c71db5Thread-18購買第10臺,剩余0臺
正在為用戶:c32654dbThread-17 處理訂單
用戶:c32654dbThread-17無法購買,已售罄!
正在為用戶:df94370aThread-7 處理訂單
用戶:df94370aThread-7無法購買,已售罄!
正在為用戶:0af94cddThread-5 處理訂單
用戶:0af94cddThread-5無法購買,已售罄!
正在為用戶:e52428a4Thread-13 處理訂單
用戶:e52428a4Thread-13無法購買,已售罄!
正在為用戶:46f91208Thread-10 處理訂單
用戶:46f91208Thread-10無法購買,已售罄!
正在為用戶:e0ca87bbThread-9 處理訂單
用戶:e0ca87bbThread-9無法購買,已售罄!
正在為用戶:f385af9aThread-8 處理訂單
用戶:f385af9aThread-8無法購買,已售罄!
正在為用戶:46c5f498Thread-6 處理訂單
用戶:46c5f498Thread-6無法購買,已售罄!
正在為用戶:935e0f50Thread-3 處理訂單
用戶:935e0f50Thread-3無法購買,已售罄!
正在為用戶:d3eaae29Thread-4 處理訂單
用戶:d3eaae29Thread-4無法購買,已售罄!

不加鎖場景
如果注釋掉加鎖代碼,變成無鎖情況,則搶購無序。
//測試類中注釋兩行用于加鎖的代碼:
public void handleOder() {

String userName = UUID.randomUUID().toString().substring(0,8) + Thread.currentThread().getName();
//加鎖代碼
//String identifier = DLock.getLockWithTimeout("Huawei Mate 10", 10000, 2000);
System.out.println("正在為用戶:" + userName + " 處理訂單");
if(n > 0) {
    int num = MAX - n + 1;
    System.out.println("用戶:"+ userName + "夠買第" + num + "臺,剩余" + (--n) + "臺");
}else {
    System.out.println("用戶:"+ userName + "無法夠買,已售罄!");
}
//加鎖代碼
//DLock.releaseLock("Huawei Mate 10", identifier);

}

注釋加鎖代碼后的運行結果,可以看出處理過程是無序的:
正在為用戶:e04934ddThread-5 處理訂單
正在為用戶:a4554180Thread-0 處理訂單
用戶:a4554180Thread-0購買第2臺,剩余8臺
正在為用戶:b58eb811Thread-10 處理訂單
用戶:b58eb811Thread-10購買第3臺,剩余7臺
正在為用戶:e8391c0eThread-19 處理訂單
正在為用戶:21fd133aThread-13 處理訂單
正在為用戶:1dd04ff4Thread-6 處理訂單
用戶:1dd04ff4Thread-6購買第6臺,剩余4臺
正在為用戶:e5977112Thread-3 處理訂單
正在為用戶:4d7a8a2bThread-4 處理訂單
用戶:e5977112Thread-3購買第7臺,剩余3臺
正在為用戶:18967410Thread-15 處理訂單
用戶:18967410Thread-15購買第9臺,剩余1臺
正在為用戶:e4f51568Thread-14 處理訂單
用戶:21fd133aThread-13購買第5臺,剩余5臺
用戶:e8391c0eThread-19購買第4臺,剩余6臺
正在為用戶:d895d3f1Thread-12 處理訂單
用戶:d895d3f1Thread-12無法購買,已售罄!
正在為用戶:7b8d2526Thread-11 處理訂單
用戶:7b8d2526Thread-11無法購買,已售罄!
正在為用戶:d7ca1779Thread-8 處理訂單
用戶:d7ca1779Thread-8無法購買,已售罄!
正在為用戶:74fca0ecThread-1 處理訂單
用戶:74fca0ecThread-1無法購買,已售罄!
用戶:e04934ddThread-5購買第1臺,剩余9臺
用戶:e4f51568Thread-14購買第10臺,剩余0臺
正在為用戶:aae76a83Thread-7 處理訂單
用戶:aae76a83Thread-7無法購買,已售罄!
正在為用戶:c638d2cfThread-2 處理訂單
用戶:c638d2cfThread-2無法購買,已售罄!
正在為用戶:2de29a4eThread-17 處理訂單
用戶:2de29a4eThread-17無法購買,已售罄!
正在為用戶:40a46ba0Thread-18 處理訂單
用戶:40a46ba0Thread-18無法購買,已售罄!
正在為用戶:211fd9c7Thread-9 處理訂單
用戶:211fd9c7Thread-9無法購買,已售罄!
正在為用戶:911b83fcThread-16 處理訂單
用戶:911b83fcThread-16無法購買,已售罄!
用戶:4d7a8a2bThread-4購買第8臺,剩余2臺

總的來說,使用DCS服務中Redis類型的緩存實例實現分布式加鎖,有幾大優勢:
1、加鎖操作簡單,使用SET、GET、DEL等幾條簡單命令即可實現鎖的獲取和釋放。
2、性能優越,緩存數據的讀寫優于磁盤數據庫與Zookeeper。
3、可靠性強,DCS有主備和集群實例類型,避免單點故障。

以上代碼實現僅展示使用DCS服務進行加鎖訪問的便捷性,具體技術實現需要考慮死鎖、鎖的檢查等情況,歡迎點擊分布式緩存服務DCS了解更多。

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/62000.html

相關文章

  • 墻裂推薦:搜云庫技術團隊,面試必備的技術干貨

    摘要:今天整理了一下近大半年以來的一些文章,和我的預期一樣,很多文章我都忘記自己曾經寫過了,這個記錄的過程讓我也有了新的理解。希望大家,收藏,點贊,加轉發。 今天整理了一下近大半年以來的一些文章,和我的預期一樣,很多文章我都忘記自己曾經寫過了,這個記錄的過程讓我也有了新的理解。希望大家,收藏,點贊,加轉發。 面試必備 面試必備:深入Spring MVC DispatchServlet 源碼...

    SegmentFault 評論0 收藏0
  • 墻裂推薦:搜云庫技術團隊,面試必備的技術干貨

    摘要:今天整理了一下近大半年以來的一些文章,和我的預期一樣,很多文章我都忘記自己曾經寫過了,這個記錄的過程讓我也有了新的理解。希望大家,收藏,點贊,加轉發。 今天整理了一下近大半年以來的一些文章,和我的預期一樣,很多文章我都忘記自己曾經寫過了,這個記錄的過程讓我也有了新的理解。希望大家,收藏,點贊,加轉發。 面試必備 面試必備:深入Spring MVC DispatchServlet 源碼...

    Neilyo 評論0 收藏0
  • java篇

    摘要:多線程編程這篇文章分析了多線程的優缺點,如何創建多線程,分享了線程安全和線程通信線程池等等一些知識。 中間件技術入門教程 中間件技術入門教程,本博客介紹了 ESB、MQ、JMS 的一些知識... SpringBoot 多數據源 SpringBoot 使用主從數據源 簡易的后臺管理權限設計 從零開始搭建自己權限管理框架 Docker 多步構建更小的 Java 鏡像 Docker Jav...

    honhon 評論0 收藏0
  • 從小白程序員一路晉升為大廠高級技術專家我看過哪些書籍?(建議收藏)

    摘要:大家好,我是冰河有句話叫做投資啥都不如投資自己的回報率高。馬上就十一國慶假期了,給小伙伴們分享下,從小白程序員到大廠高級技術專家我看過哪些技術類書籍。 大家好,我是...

    sf_wangchong 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<