亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Redis在多線程情況下寫入失敗的問(wèn)題及解決

 更新時(shí)間:2025年11月06日 09:03:36   作者:我惠依舊  
文章描述了在JRE 7 32位環(huán)境下使用Jedis客戶端并發(fā)調(diào)用`set`方法時(shí)出現(xiàn)的問(wèn)題,懷疑是多線程環(huán)境下獲取連接導(dǎo)致的卡死,通過(guò)使用連接池和在JDK 8 64位環(huán)境下進(jìn)行測(cè)試,問(wèn)題得到解決

出現(xiàn)場(chǎng)景

同一時(shí)間多次調(diào)用jedis的set方法,出現(xiàn):

redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketException: Socket is not connected: socket write error
    at redis.clients.jedis.Protocol.sendCommand(Protocol.java:98)
    at redis.clients.jedis.Protocol.sendCommand(Protocol.java:78)
    at redis.clients.jedis.Connection.sendCommand(Connection.java:101)
    at redis.clients.jedis.BinaryClient.set(BinaryClient.java:99)
    at redis.clients.jedis.Client.set(Client.java:29)
    at redis.clients.jedis.Jedis.set(Jedis.java:72)
    at com.castle.cache.JedisUtils.setSingle(JedisUtils.java:21)
    at com.castle.cache.JedisUtils$1.run(JedisUtils.java:36)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)
Caused by: java.net.SocketException: Socket is not connected: socket write error
    at java.net.SocketOutputStream.socketWrite0(Native Method)
    at java.net.SocketOutputStream.socketWrite(Unknown Source)
    at java.net.SocketOutputStream.write(Unknown Source)
    at redis.clients.util.RedisOutputStream.flushBuffer(RedisOutputStream.java:31)
    at redis.clients.util.RedisOutputStream.write(RedisOutputStream.java:38)
    at redis.clients.jedis.Protocol.sendCommand(Protocol.java:84)
    ... 10 more

問(wèn)題重現(xiàn)代碼

環(huán)境:jre7 32bit

jedis:

        <dependency>
			<groupId>redis.clients</groupId>
			<artifactId>jedis</artifactId>
			<version>2.7.3</version>
			<type>jar</type>
			<scope>compile</scope>
		</dependency>
private static Jedis jedis = new Jedis("localhost",6379);;
	// 過(guò)期時(shí)間/生存時(shí)間
//    protected static int  expireTime = 60 * 60 *24;
	public static Jedis getInstance(){
		return jedis;
	}
	
	public static void setSingle(String key,String value){
		jedis.set(key, value);
//		jedis.expire(key, expireTime);
	}
	
	public static String getSingle(String key){
//		jedis.expire(key, expireTime);
		return jedis.get(key);
	}
	
	public static void main(String[] args) {
		ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
        for (int i = 1; i <= 1000; i++) {
            final String ii = "TEST:TEST_NUM-"+i;
            cachedThreadPool.execute(new Thread(){
            	public void run(){
            		setSingle(ii, ii);
            	}
            });
        }
	}

運(yùn)行代碼然后就出現(xiàn):

原因分析

猜測(cè)多線程獲取連接,同一時(shí)間獲取同一個(gè)連接導(dǎo)致卡死

解決方案

擬用連接池:

private static JedisPool pool;
	/**
     * 初始化Redis連接池
     */
    private static void initializePool() {
		//redisURL 與 redisPort 的配置文件
        JedisPoolConfig config = new JedisPoolConfig();
		//設(shè)置最大連接數(shù)(100個(gè)足夠用了,沒(méi)必要設(shè)置太大)
		config.setMaxTotal(20);
		//最大空閑連接數(shù)
		config.setMaxIdle(5);
		//獲取Jedis連接的最大等待時(shí)間(50秒) 
		config.setMaxWaitMillis(50 * 1000);
		//在獲取Jedis連接時(shí),自動(dòng)檢驗(yàn)連接是否可用
		config.setTestOnBorrow(true);
		//在將連接放回池中前,自動(dòng)檢驗(yàn)連接是否有效
		config.setTestOnReturn(true);
		//自動(dòng)測(cè)試池中的空閑連接是否都是可用連接
		config.setTestWhileIdle(true);
		//創(chuàng)建連接池
		pool = new JedisPool(config, "localhost",6379);
    }
 
    /**
     * 多線程環(huán)境同步初始化(保證項(xiàng)目中有且僅有一個(gè)連接池)
     */
    private static synchronized void poolInit() {
        if (null == pool) {
            initializePool();
        }
    }
	
	public static Jedis getJedis() {

	       if (pool == null) {
	           poolInit();
	       }
	       //如果沒(méi)有以下代碼會(huì)造成初始化的jedis拿不到 jedis對(duì)象
	       Jedis jedis = null;
	       try {
	           if (pool != null) {
	               jedis = pool.getResource();
	           }
	       }
	       catch (Exception e) {
	           e.printStackTrace();
	       }
	       return jedis;
	   }
	
	/**
     * 釋放Jedis資源
     *
     * @param jedis
     */
    public static void returnResource(Jedis jedis) {
        if (null != jedis) {
            pool.returnResourceObject(jedis);
        }
    }
	
	//private static Jedis jedis = new Jedis("localhost",6379);;
//	public static Jedis getInstance(){
//		return jedis;
//	}
	// 過(guò)期時(shí)間/生存時(shí)間
    protected static int  expireTime = 60 * 60 *24;
	
	public static void put(String key,String value){
//		jedis.set(key, value);
		Jedis jedis = getJedis();
        while (true) {
            if (null != jedis) {
                break;
            } else {
                jedis = getJedis();
            }
        }
        jedis.set(key, value);
        returnResource(jedis);
//		jedis.expire(key, expireTime);
	}
	
	public static String get(String key){
//		jedis.expire(key, expireTime);
//		return jedis.get(key);
		Jedis jedis = getJedis();
        while (true) {
            if (null != jedis) {
                break;
            } else {
                jedis = getJedis();
            }
        }
        String value = jedis.get(key);
        returnResource(jedis);
        return value;
	}
	
	public static Set<String> keys(String keyMatch){
//		jedis.expire(key, expireTime);
//		
		Jedis jedis = getJedis();
        while (true) {
            if (null != jedis) {
                break;
            } else {
                jedis = getJedis();
            }
        }
        Set<String> res = jedis.keys(keyMatch);
        returnResource(jedis);
        return res;
	}
	
	public static void remove(String key){
//		jedis.del(key);
		Jedis jedis = getJedis();
        while (true) {
            if (null != jedis) {
                break;
            } else {
                jedis = getJedis();
            }
        }
        jedis.del(key);
        returnResource(jedis);
	}

測(cè)試代碼:

public static void main(String[] args) {
		ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
        for (int i = 1; i <= 1000; i++) {
            final String ii = "TEST:TEST_NUM-"+i;
            cachedThreadPool.execute(new Thread(){
            	public void run(){
            		put(ii, ii);
            	}
            });
        }
	}

插入成功:

這是在jdk7 32位的情況下,我在jdk8 64位運(yùn)行會(huì)報(bào)異常的代碼仍然能插入。

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Redis中三種特殊數(shù)據(jù)類型命令詳解

    Redis中三種特殊數(shù)據(jù)類型命令詳解

    Geospatial是地理位置類型,我們可以用來(lái)查詢附近的人、計(jì)算兩人之間的距離等,這篇文章主要介紹了Redis中三種特殊數(shù)據(jù)類型命令詳解,需要的朋友可以參考下
    2024-05-05
  • Redis+Caffeine實(shí)現(xiàn)多級(jí)緩存的步驟

    Redis+Caffeine實(shí)現(xiàn)多級(jí)緩存的步驟

    隨著不斷的發(fā)展,這一架構(gòu)也產(chǎn)生了改進(jìn),在一些場(chǎng)景下可能單純使用Redis類的遠(yuǎn)程緩存已經(jīng)不夠了,還需要進(jìn)一步配合本地緩存使用,例如Guava cache或Caffeine,從而再次提升程序的響應(yīng)速度與服務(wù)性能,這篇文章主要介紹了Redis+Caffeine實(shí)現(xiàn)多級(jí)緩存,需要的朋友可以參考下
    2024-01-01
  • Redis Caffeine實(shí)現(xiàn)兩級(jí)緩存的項(xiàng)目實(shí)踐

    Redis Caffeine實(shí)現(xiàn)兩級(jí)緩存的項(xiàng)目實(shí)踐

    本文介紹了使用Redis和Caffeine實(shí)現(xiàn)兩級(jí)緩存,以提高查詢接口的性能,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-12-12
  • 利用Redis?lua實(shí)現(xiàn)高效讀寫鎖的代碼實(shí)例

    利用Redis?lua實(shí)現(xiàn)高效讀寫鎖的代碼實(shí)例

    這篇文章給大家介紹了如何利用Redis?lua實(shí)現(xiàn)高效的讀寫鎖,讀寫鎖的好處就是能幫助客戶讀到的數(shù)據(jù)一定是最新的,寫鎖是排他鎖,而讀鎖是一個(gè)共享鎖,需要的朋友可以參考下
    2024-01-01
  • 解讀redis?slaveof命令執(zhí)行后為什么需要清庫(kù)重新同步

    解讀redis?slaveof命令執(zhí)行后為什么需要清庫(kù)重新同步

    這篇文章主要介紹了redis?slaveof命令執(zhí)行后為什么需要清庫(kù)重新同步,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2025-04-04
  • K8S部署Redis(單機(jī)、集群)的超詳細(xì)步驟

    K8S部署Redis(單機(jī)、集群)的超詳細(xì)步驟

    redis是一款基于BSD協(xié)議,開(kāi)源的非關(guān)系型數(shù)據(jù)庫(kù)(nosql數(shù)據(jù)庫(kù))這篇文章主要給大家介紹了關(guān)于K8S部署Redis(單機(jī)、集群)的超詳細(xì)步驟,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-05-05
  • Redis?sentinel哨兵集群的實(shí)現(xiàn)步驟

    Redis?sentinel哨兵集群的實(shí)現(xiàn)步驟

    本文主要介紹了Redis?sentinel哨兵集群的實(shí)現(xiàn)步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-07-07
  • Redis如何存儲(chǔ)對(duì)象

    Redis如何存儲(chǔ)對(duì)象

    這篇文章主要介紹了Redis如何存儲(chǔ)對(duì)象,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • Linux下Redis安裝使用教程

    Linux下Redis安裝使用教程

    這篇文章主要為大家詳細(xì)介紹了Linux下Redis安裝使用教程,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-09-09
  • Redis分布式限流的幾種實(shí)現(xiàn)

    Redis分布式限流的幾種實(shí)現(xiàn)

    分布式限流是指通過(guò)將限流策略嵌入到分布式系統(tǒng)中,以控制流量或保護(hù)服務(wù),本文就來(lái)介紹一下Redis分布式限流的幾種實(shí)現(xiàn),感興趣的可以了解一下
    2023-12-12

最新評(píng)論