前言
這一篇文章將講述Redis中的list類型命令,同樣也是通過demo來講述,其他部分這裏就不在贅述了。
項目Github地址:https://github.com/rainbowda/...
案例
demo功能是隊列,整個demo的大致頁面如下。左邊是存儲到Redis中的數據,右邊是從Redis中彈出的數據。
準備工作
首先定義一個存儲list的key
隊列的key就用list:1
redis操作對象
list在Redis中的結構可以看下圖(圖片來源於Redis in Action)。
插入數據
頭部插入
命令介紹
接下來看看demo中頭部插入的功能,點擊下圖中頭部插入按鈕,然後在彈出框中填入數字0,點擊提交後整個頭部插入流程結束。可以看到左邊的隊列數據出現了一條{"data":"0"} 數據,在數據{"data":"1"} 上面。
來看看後臺的方法
如果需要在Redis中操作,可以敲下面的命令
尾部插入
命令介紹
接下來看看demo中尾部插入的功能,點擊下圖中尾部插入按鈕,然後在彈出框中填入數字11,點擊提交後整個新增流程結束。可以看到左邊的隊列數據出現了一條{"data":"11"} 數據,在數據{"data":"10"}下面。
來看看後臺的方法
如果需要在Redis中操作,可以敲下面的命令
列表查詢
命令介紹
同樣先看看相關的獲取值命令
後臺查詢方法,將新增的內容查詢出來
數據彈出
頭部彈出
接下來看看頭部彈出的功能,點擊下圖中頭部彈出按鈕,可以看到左邊的隊列頂部數據減少了,在右邊彈出的數據出現了左邊隊列數據消失的數據。
來看看後臺的方法
如果需要在Redis中操作,可以敲下面的命令
尾部彈出
接下來看看尾部彈出的功能,點擊下圖中尾部彈出按鈕,可以看到左邊的隊列尾部數據減少了,在右邊彈出的數據出現了左邊隊列數據消失的數據。
來看看後臺的方法
如果需要在Redis中操作,可以敲下面的命令
其他命令
RPOPLPUSH和BRPOPLPUSH
這兩個命令作用其實是相同的,只不過BRPOPLPUSH是阻塞的,當沒有數據時,會一直阻塞,直到有數據。
在Redis官方文檔中,用RPOPLPUSH命令舉了兩個例子,一個是Reliable queue(安全的隊列 ),另一個是Circular list(循環列表)。
Reliable queue(安全的隊列 )
Redis通常都被用做一個處理各種後臺工作或消息任務的消息服務器。 一個簡單的隊列模式就是:生產者把消息放入一個列表中,等待消息的消費者用 RPOP 命令(用輪詢方式), 或者用 BRPOP 命令(如果客戶端使用阻塞操作會更好)來得到這個消息。然而,因爲消息有可能會丟失,所以這種隊列並是不安全的。例如,當接收到消息後,出現了網絡問題或者消費者端崩潰了, 那麼這個消息就丟失了。
RPOPLPUSH (或者其阻塞版本的 BRPOPLPUSH)
提供了一種方法來避免這個問題:消費者端取到消息的同時把該消息放入一個正在處理中的列表。 當消息被處理了之後,該命令會使用 LREM
命令來移除正在處理中列表中的對應消息。另外,可以添加一個客戶端來監控這個正在處理中列表,如果有某些消息已經在這個列表中存在很長時間了(即超過一定的處理時限),
那麼這個客戶端會把這些超時消息重新加入到隊列中。
Circular list(循環列表)
RPOPLPUSH 命令的 source 和 destination 是相同的話, 那麼客戶端在訪問一個擁有n個元素的列表時,可以在 O(N) 時間裏一個接一個獲取列表元素, 而不用像 LRANGE 那樣需要把整個列表從服務器端傳送到客戶端。上面這種模式即使在以下兩種情況下照樣能很好地工作:
有多個客戶端同時對同一個列表進行旋轉(rotating):它們會取得不同的元素,直到列表裏所有元素都被訪問過,又從頭開始這個操作。
有其他客戶端在往列表末端加入新的元素。這個模式讓我們可以很容易地實現這樣一個系統:有 N 個客戶端,需要連續不斷地對一批元素進行處理,而且處理的過程必須儘可能地快。
一個典型的例子就是服務器上的監控程序:它們需要在儘可能短的時間內,並行地檢查一批網站,確保它們的可訪問性。值得注意的是,使用這個模式的客戶端是易於擴展(scalable)且安全的(reliable),因爲即使客戶端把接收到的消息丟失了,
這個消息依然存在於隊列中,等下次迭代到它的時候,由其他客戶端進行處理。
案例-約瑟夫問題
約瑟夫問題(有時也稱爲約瑟夫斯置換),是一個出現在計算機科學和數學中的問題。在計算機編程的算法中,類似問題又稱爲約瑟夫環。人們站在一個等待被處決的圈子裏。 計數從圓圈中的指定點開始,並沿指定方向圍繞圓圈進行。 在跳過指定數量的人之後,執行下一個人。
對剩下的人重複該過程,從下一個人開始,朝同一方向跳過相同數量的人,直到只剩下一個人,並被釋放。問題即,給定人數、起點、方向和要跳過的數字,選擇初始圓圈中的位置以避免被處決。
思路
定義一個list key爲josephus,利用
命令來構造循環鏈表,每當數到3時,使用rpop
命令彈出
代碼實現
整個代碼步驟如下
- 先是模擬有41個人(向redis中key爲josephus的list添加41個數據)
- 定義索引index
- 循環判斷key爲josephus的數據長度是否大於0
- 當索引index爲3時,調用Redis的rpop命令彈出對應的數據。索引index不爲3時,調用RPOPLPUSH命令,將對應的數據放到隊列頭部
- 索引index加1
運行結果有點長,這裏只截圖最後一部分的結果,如下
約瑟夫問題代碼請點擊JosephusProblem.java
建議學習的人最好每個命令都去敲下,加深印象。下面詩句送給你們。紙上得來終覺淺,絕知此事要躬行。————出自《冬夜讀書示子聿》
本文作者: 勿妄
本文爲雲棲社區原創內容,未經允許不得轉載。