最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Redis在多線程情況下寫入失敗的問題及解決

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

出現(xiàn)場景

同一時間多次調(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

問題重現(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);;
	// 過期時間/生存時間
//    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):

原因分析

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

解決方案

擬用連接池:

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

	       if (pool == null) {
	           poolInit();
	       }
	       //如果沒有以下代碼會造成初始化的jedis拿不到 jedis對象
	       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;
//	}
	// 過期時間/生存時間
    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);
	}

測試代碼:

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)行會報異常的代碼仍然能插入。

總結(jié)

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

相關(guān)文章

  • Redis 數(shù)值范圍查詢(Numeric Range Queries)的實(shí)現(xiàn)

    Redis 數(shù)值范圍查詢(Numeric Range Queries)的實(shí)現(xiàn)

    本文主要介紹了Redis 數(shù)值范圍查詢(Numeric Range Queries)的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2025-11-11
  • Redis模仿發(fā)送手機(jī)驗(yàn)證碼功能

    Redis模仿發(fā)送手機(jī)驗(yàn)證碼功能

    這篇文章主要介紹了Redis模仿手機(jī)驗(yàn)證碼發(fā)送功能,通過示例代碼給大家講解通過用戶輸入手機(jī)號以及驗(yàn)證碼進(jìn)行校驗(yàn),代碼簡單易懂,需要的朋友可以參考下
    2021-09-09
  • Java實(shí)現(xiàn)多級緩存的方法詳解

    Java實(shí)現(xiàn)多級緩存的方法詳解

    對于高并發(fā)系統(tǒng)來說,有三個重要的機(jī)制來保障其高效運(yùn)行,它們分別是:緩存、限流和熔斷,所以本文就來和大家探討一下多級緩存的實(shí)現(xiàn)方法,希望對大家有所幫助
    2024-02-02
  • 詳解Redis中數(shù)值亂碼的根本原因以及解決方式

    詳解Redis中數(shù)值亂碼的根本原因以及解決方式

    這篇文章給大家詳細(xì)分析了Redis中數(shù)值亂碼的根本原因以及解決方式,通過代碼示例給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下
    2024-02-02
  • 最新評論

    定州市| 临高县| 新乐市| 四会市| 凌云县| 鱼台县| 哈密市| 布拖县| 高安市| 兴城市| 拉孜县| 武功县| 洛宁县| 凤台县| 河源市| 萝北县| 闽清县| 拉萨市| 理塘县| 伊金霍洛旗| 历史| 阿图什市| 扶沟县| 连城县| 平潭县| 三亚市| 将乐县| 建始县| 高雄市| 尖扎县| 宁南县| 密山市| 恩施市| 滦平县| 博爱县| 宽城| 桂林市| 扎囊县| 上林县| SHOW| 巴塘县|