1. 程式人生 > >Redis研究(七)—如何判斷set/get是否為原子操作

Redis研究(七)—如何判斷set/get是否為原子操作

在做專案過程中,多個客戶端可能同時讀寫Redis資料庫,set和get命令是否為原子操作,關係到命令是否需要加鎖機制的必要性。網上資料或者看書都說set和get等Redis命令為原子操作,但是程式裡怎麼測試呢?

試想開1000個寫執行緒,1000個讀執行緒同時操作Redis中的一個值,假如set和get不是原子的,那麼當set的時候,把原來資料塗掉,還沒來得及寫進去,get操作已經執行,這個時候get到的值就可能為髒資料。如果get得到的值都為正確的資料,基本能判斷set和get命令為原子操作。

下面程式碼測試:

封裝好的Redis讀寫類:

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;


public class RedisUtils {

	private Jedis jedis;
	private JedisPool jedisPool;

	public RedisUtils() {
		initialPool();
		jedis = jedisPool.getResource();
	}


	private void initialPool() {
		JedisPoolConfig config = new JedisPoolConfig();
		config.setMaxActive(100);
		config.setMaxIdle(20);
		config.setMaxWait(1000l);
		config.setTestOnBorrow(false);
		
		jedisPool = new JedisPool(config, "127.0.0.1", 6379);

	}


	public String get(String key) {
		String getStr = jedis.get(key);
		return getStr;
	}

	public String set(String key, String value) {
		String setStr = jedis.set(key, value);
		return setStr;
	}

}

1000個寫執行緒:

package writeTest;

public class writeTest extends Thread {

	public writeTest(String s) {
		super(s);
	}

	public void run() {
		RedisUtils ru = new RedisUtils();
		while (true) {
			try {
				String s = ru.set("test", "100");
				System.out.println(getName() + "===" + "done");
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	public static void main(String[] args) {
		for (int i = 0; i < 1000; i++) {
			String threadName = "WThread" + i;
			new writeTest(threadName).start();
		}
	}
}

1000個讀執行緒

package readTest;

public class readTest extends Thread {

	public readTest(String s) {
		super(s);
	}

	public void run() {
		RedisUtils ru = new RedisUtils();
		while (true) {
			try {
				String s = ru.get("test");
				System.out.println(getName() + "===" + s);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	public static void main(String[] args) {
		for (int i = 0; i < 1000; i++) {
			String threadName = "RThread" + i;
			new readTest(threadName).start();
		}
	}
}

同時執行上述讀執行緒,和寫執行緒,看控制檯輸出get到的值是否有髒資料。

發現RThread執行緒get讀出來的數都是100,沒有髒資料,即可判斷set和get為原子操作。

相關推薦

Redis研究—如何判斷set/get是否原子操作

在做專案過程中,多個客戶端可能同時讀寫Redis資料庫,set和get命令是否為原子操作,關係到命令是否需要加鎖機制的必要性。網上資料或者看書都說set和get等Redis命令為原子操作,但是程式裡怎麼測試呢? 試想開1000個寫執行緒,1000個讀執行緒同時操作Redi

Redisset/get 命令解析

  經過前兩篇的介紹,我們對整個redis的動作流程已經有比較清晰的認識。   接下來就是到具體的命令處理方式的理解了,想來我們用這些工具的意義也是在此。雖然沒有人覺得,一個set/get方法會有難度,但是我們畢竟不是很清楚,否則也不至於在談到深處就懵逼了。   我覺得本文的一個重要意義就是: 讓set/ge

Redisset/sadd/sismember/sinter/sdiffstore 命令原始碼解析

  上兩篇我們講了hash和list資料型別相關的主要實現方法,同時加上前面對框架服務和string相關的功能介紹,已揭開了大部分redis的實用面紗。   現在還剩下兩種資料型別: set, zset.   本篇咱們繼續來看redis中的資料型別的實現: set 相關操作實現。     研究過jd

Redis研究—簡介

創始人 存儲結構 隊列 cached tar 寫入 關系 退出 使用 http://blog.csdn.net/wtyvhreal/article/details/41855327 Redis是一個開源的高性能鍵值對數據庫。它通過提供多種鍵值數據類型來適應不同場景下的

redis 實驗監控和性能

系統/運維 Linux redis-cli monitor可以實時看到命令情況可以跑一個性能測試redis-benchmark -c 10 -n 100000 -qredis 實驗(七)監控和性能

Redis入門Redis分散式鎖單機模式/叢集模式

Redis 實現分散式鎖 單機模式的Redis分散式鎖 優缺點 實現比較輕,大多數時候能滿足需求;因為是單機單例項部署,如果redis服務宕機,那麼所有需要獲取分散式鎖的地方均無法獲取鎖,將全部阻塞,需要做好降級處理。 當鎖過期後,執行任務的程序還沒有

redis 系列 redis API使用

Jedis redis單機版  java API 操作  package bhz.redis01; import org.apache.commons.pool2.impl.GenericObjectPoolConfig; import org.junit.Aft

Redis學習 Redis 持久化之RDB和AOF

Redis 持久化提供了多種不同級別的持久化方式:一種是RDB,另一種是AOF.   RDB 持久化可以在指定的時間間隔內生成資料集的時間點快照(point-in-time snapshot)。   AOF 持久化記錄伺服器執行的所有寫操作命令,並在伺服器啟動時,通過重新執行這些命令來還原資

Redis研究—字串型別

在介紹Redis字串型別之前,先來了解幾個比較基礎的命令作為熱身。 1.獲得符合規則的鍵名列表 keys patternpattern支援glob風格萬用字元格式,具體規則如下: ? 匹配一個字元 * 匹配任意個(包括0個)字元 [] 匹配括號間的任一字元,可以使用“-

Redis研究—雜湊型別

雜湊型別(hash)的鍵值也是一種字典結構,其儲存了欄位(field)和欄位值的對映,但欄位值只能是字串,不支援其他資料型別。 雜湊型別不能巢狀其他的資料型別。一個雜湊型別鍵可以包含至多2^32-1個欄位。 一、介紹 雜湊型別適合儲存物件:使用物件類別和ID構成鍵名,使用

怎樣做研究 劉挺

在事業上每10年就是一代人,我們這一代(70年前後出生)是承前啟後的一代。我們讀書的年代沒有網際網路,與國際的交往也非常少,聽說過ACL/Coling就不錯了,都沒想過去參加。在這種相對封閉的條件下成長起來的人,要想在一個點上做出國際領先的成果,是非常困難的。博士畢業後,多數

OpenWRT研究——自己編譯虛擬機器VitrualBox映象

所使用系統環境VirtualBox下CentOS 6.5 64Bit,宿主機Mac OX 10.9.3 VirtualBox  4.3.12 r93733,注意編譯過程中要保證磁碟空間,我新建的虛擬機器磁碟大小為50G,編譯使用了15G。 一、下載原始碼到本地 svn co

Redis系列Redis面試題

**Redis 系列:** 1. [Redis系列(一)Redis入門](https://blog.itzhouq.cn/redis1) 2. [Redis系列(二)Redis的8種資料型別](https://blog.itzhouq.cn/redis2) 3. [Redis系列(三)Redis的事務和Sp

Uniyt熱更新——LuaFrameWork學習判斷unity裡物件

在遊戲製作過程中我們經常會Destroy一些沒用的GameObject,那麼在ulua裡我們怎麼樣來判斷我們的引用被Destroy了呢,這裡要感謝阿盟哥,他已經為我們解決了這個問題,在他寫的Globa

Flaskflash與前臺交互get post

視圖 return 限制 編碼 sed dem code src log Project name :Flask_Plan templates:templates static:static 兩種 HTTP 請求方法:GET 和 POST在客戶機和服務器之間進行請求-響應時

Centos7 minimal 系列之Redis共享sessionid

image strings 系列 sha edi esp get blog 用戶 這一章節的內容就當看看,只是個人理解,我想應該是有誤的。 一、SessionId   sessionid是一個會話的key,瀏覽器第一次訪問服務器會在服務器端生成一個session,有一個se

Redis 設計與實現 --事務

實現 標識 AC redis 服務 監視 不執行 get 狀態切換 事務 *ACID,指數據庫事務正確執行的四個基本要素的縮寫。包含:原子性(Atomicity)、一致性(Consistency)、隔離性(Isolation)、持久性(Durability) redis

Redis入門到高可用——無序set

sca image com 無序 實戰 關系 ans srand article 一、結構 特點:無序,無重復,支持集合間操作 二、主要API smembers : 無序;(會阻塞)小心使用,可用sscan代替 spop: 從集合中彈出元素,每次只

條件判斷語句

== 們的 技術 AR 就是 body endif 存在 條件判斷 我們之前說過 makefile 是一種腳本語言程序,那麽程序便會有相應的語法。在 makefile 中支持條件判斷語句,可以根據條件的值來決定 make 的執行,也可以比較兩個不同變量或者變

Redis對鍵key的操作

amp rename ace 排序 sta pla time second att key的全部命令如下: keys pattern # 查找所有符合給定模式pattern的key ,查找所有key 使用[