redis incr incrby decr decrby命令

redis中incr、incrby、decr、decrby屬於string數據結構,它們是原子性遞增或遞減操做。redis

  • incr遞增1並返回遞增後的結果;
  • incrby根據指定值作遞增或遞減操做並返回遞增或遞減後的結果(incrby遞增或遞減取決於傳入值的正負);
  • decr遞減1並返回遞減後的結果;
  • decrby根據指定值作遞增或遞減操做並返回遞增或遞減後的結果(decrby遞增或遞減取決於傳入值的正負);

設置incr:key和decr:key觀察用法和執行結果數據結構

1.首次觀察incr:key的值,能夠看到沒有結果併發

127.0.0.1:6381> GET incr:key

127.0.0.1:6381>

2.對incr:key執行incr命令,能夠看到redis返回了遞增後的結果1。incr命令會返回遞增後的結果ide

127.0.0.1:6381> incr incr:key
1
127.0.0.1:6381>

3.對incr:key執行incrby命令,能看到redis返回了遞增後的結果5。incrby命令會返回遞增後的結果網站

127.0.0.1:6381> incrby incr:key 4
5
127.0.0.1:6381>

4.對incr:key執行incrby命令,此次傳入一個負數,能觀察到redis返回了遞減後的結果2spa

127.0.0.1:6381> incrby incr:key -3
2
127.0.0.1:6381>

5.對incr:key執行incrby命令,一樣傳入負數, 能夠觀察到incr:key通過遞減後結果變成了負數線程

127.0.0.1:6381> incrby incr:key -4
-2
127.0.0.1:6381>

6.首次觀察decr:key,沒有任何結果接口

127.0.0.1:6381> GET decr:key

127.0.0.1:6381>

7.對decr:key執行decr命令,能夠看到redis返回了遞減後的結果ip

127.0.0.1:6381> decr decr:key
-1
127.0.0.1:6381>

8.對decr:key執行decrby命令,能夠看到redis返回了遞減後的結果,這裏的值輸入的是4而不是-4get

127.0.0.1:6381> decrby decr:key 4
-5
127.0.0.1:6381>

9.對decr:key執行decrby命令,此次輸入一個負數,觀察一下結果

127.0.0.1:6381> decrby decr:key -1
-4
127.0.0.1:6381>

 

併發遞增和遞減

  作一個實驗,併發100個線程對同一個key作操做,其中50個執行incr命令,另外50個執行decr命令,觀察一下結果

複製代碼

/**
 * 併發100個線程,50個線程作decr命令,另外50個線程作incr命令
 *
 * @author tianshu on 16/10/31 上午10:52.
 */
public class MultipleDecrIncr {

    /** decr線程數量 */
    private static final int DECR_THREAD_COUNT = 50;
    /** incr線程數量 */
    private static final int INCR_THREAD_COUNT = 50;

    private static CountDownLatch begin = new CountDownLatch(DECR_THREAD_COUNT + INCR_THREAD_COUNT);

    private static CountDownLatch finish = new CountDownLatch(DECR_THREAD_COUNT + INCR_THREAD_COUNT);

    static final String KEY = "string:decr:incr";


    public static void main(String[] args) throws InterruptedException {

        for(int i = 0; i < DECR_THREAD_COUNT; ++i) {
            new DecrThread().start();
            begin.countDown();
        }

        for(int i = 0; i < INCR_THREAD_COUNT; ++i) {
            new IncrThread().start();
            begin.countDown();
        }

        finish.await();

        JedisConnect jedisConnect = JedisConnect.getJedisConnect();
        Jedis jedis = jedisConnect.getJedis();

        String value = jedis.get(KEY);
        System.out.println(value);

        jedisConnect.releaseJedis(jedis);
    }

    /**
     * decr命令線程
     */
    static class DecrThread extends Thread {

        @Override
        public void run() {

            try {
                begin.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            JedisConnect jedisConnect = JedisConnect.getJedisConnect();
            Jedis jedis = jedisConnect.getJedis();

            jedis.decr(KEY);
            jedisConnect.releaseJedis(jedis);

            finish.countDown();
        }
    }

    /**
     * incr命令線程
     */
    static class IncrThread extends Thread {

        @Override
        public void run() {

            try {
                begin.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            JedisConnect jedisConnect = JedisConnect.getJedisConnect();
            Jedis jedis = jedisConnect.getJedis();

            jedis.incr(KEY);
            jedisConnect.releaseJedis(jedis);

            finish.countDown();
        }

    }

}

複製代碼

 

應用場景

  我的以爲這類命令通常會應用到計數器場景

  • 單號生成:根據業務生成key,每當須要單號時能夠使用incr得到一個新的序列號。
  • 錯誤攔截:好比有的網站帳號密碼輸入錯誤N次以後,會作一些特殊處理;使用incr是實現這種功能的方式之一,能夠根據用戶的特殊標識表示key,每當帳號密碼輸錯時使用incr命令作遞增。
  • 非法攔截:某段時間限制同IP請求同一接口次數
相關文章
相關標籤/搜索