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

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è)足夠用了,沒必要設(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();
	       }
	       //如果沒有以下代碼會(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ù)值范圍查詢(Numeric Range Queries)的實(shí)現(xiàn)

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

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

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

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

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

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

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

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

    新丰县| 九龙坡区| 申扎县| 长汀县| 丹巴县| 枣阳市| 手机| 吐鲁番市| 克山县| 弥渡县| 自贡市| 上栗县| 韶山市| 丽江市| 奈曼旗| 本溪| 义乌市| 沙河市| 蒙自县| 新津县| 海口市| 翁牛特旗| 开平市| 文登市| 万全县| 镇远县| 河源市| 海林市| 昌都县| 张家川| 枞阳县| 华亭县| 建宁县| 湖州市| 宁乡县| 泗阳县| 东乌珠穆沁旗| 临夏市| 邯郸市| 鸡东县| 黔江区|