Jedis的连接是非线程安全的

下面是set命令的执行过程,简单分为两个过程,客户端向服务端发送数据,服务端向客户端返回数据,从下面的代码来看:从建立连接到执行命令是没有进行任何并发同步的控制

public String set(final String key, String value) {
checkIsInMulti();
// 执行set命令,其实是发送set命令和其参数到server端,实际是调用下面的SendCommond(…)方法,发送数据
client.set(key, value);
// 等待服务器响应
return client.getStatusCodeReply();
}

set 命令的数据发送过程

public static void sendCommand(final RedisOutputStream os, final Command command,
final byte[]... args) {
sendCommand(os, command.raw, args);
} private static void sendCommand(final RedisOutputStream os, final byte[] command,
final byte[]... args) {
try {
os.write(ASTERISK_BYTE);
os.writeIntCrLf(args.length + 1);
os.write(DOLLAR_BYTE);
os.writeIntCrLf(command.length);
os.write(command);
os.writeCrLf(); for (final byte[] arg : args) {
os.write(DOLLAR_BYTE);
os.writeIntCrLf(arg.length);
os.write(arg);
os.writeCrLf();
}
} catch (IOException e) {
throw new JedisConnectionException(e);
}
}

set命令接收服务端响应过程

private static Object process(final RedisInputStream is) {

  final byte b = is.readByte();
if (b == PLUS_BYTE) {
return processStatusCodeReply(is);
} else if (b == DOLLAR_BYTE) {
return processBulkReply(is);
} else if (b == ASTERISK_BYTE) {
return processMultiBulkReply(is);
} else if (b == COLON_BYTE) {
return processInteger(is);
} else if (b == MINUS_BYTE) {
processError(is);
return null;
} else {
throw new JedisConnectionException("Unknown reply: " + (char) b);
}
}

JedisPool是线程安全的

Jedis客户端支持多线程下并发执行时通过JedisPool实现的,借助于commong-pool2实现线程池,它会为每一个请求分配一个Jedis连接,在请求范围内使用完毕后记得归还连接到连接池中,所以在实际运用中,注意不要把一个Jedis实例在多个线程下并发使用,用完后要记得归还到连接池中

MySQL的连接是线程安全的

在一些简单情况下,我是不用DataSource的,一般都会采用单例的方式建立MySQL的连接,刚开始我也不晓得这样写,看别人这样写也就跟着这样写了,突然有一天我怀疑这样的写发是否可选,一个MySQL的Connection是否在多个线程下并发操作是否安全。

在JDK中定义java.sql.Connection只是一个接口,也并没有写明它的线程安全问题。查阅资料得知,它的线程安全性由对应的驱动实现:

java.sql.Connection is an interface. So, it all depends on the driver's implementation, but in general you should avoid sharing the same connection between different threads and use connection pools. Also it is also advised to have number of connections in the pool higher than number of worker threads.

这是MySQL的驱动实现,可以看到它在执行时,是采用排它锁来保证连接的在并发环境下的同步。

public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
// 在使用连接过程中是采用排它锁的方式
synchronized(this.getConnectionMutex()) {
this.checkClosed();
Object pStmt = null;
boolean canServerPrepare = true;
String nativeSql = this.getProcessEscapeCodesForPrepStmts()?this.nativeSQL(sql):sql;
if(this.useServerPreparedStmts && this.getEmulateUnsupportedPstmts()) {
canServerPrepare = this.canHandleAsServerPreparedStatement(nativeSql);
}
...
...

一般情况下,为了提高并发性,建议使用池技术来解决单链接的局限性,比如常用的一些数据源:C3P0等

Jedis 与 MySQL的连接线程安全问题的更多相关文章

  1. ASP.NET MVC深入浅出系列(持续更新) ORM系列之Entity FrameWork详解(持续更新) 第十六节:语法总结(3)(C#6.0和C#7.0新语法) 第三节:深度剖析各类数据结构(Array、List、Queue、Stack)及线程安全问题和yeild关键字 各种通讯连接方式 设计模式篇 第十二节: 总结Quartz.Net几种部署模式(IIS、Exe、服务部署【借

    ASP.NET MVC深入浅出系列(持续更新)   一. ASP.NET体系 从事.Net开发以来,最先接触的Web开发框架是Asp.Net WebForm,该框架高度封装,为了隐藏Http的无状态模 ...

  2. 关于MySQL用户会话及连接线程

    0.概念理解:用户会话和连接线程是什么关系? 用户会话和用户连接线程是一一对应的关系,一个会话就一个用户连接线程. 问题描述: 如果系统因为执行了一个非常大的dml或者ddl操作导致系统hang住,我 ...

  3. mysql交互式连接&非交互式连接

    交互式操作:通俗的说,就是你在你的本机上打开mysql的客户端,就是那个黑窗口,在黑窗口下进行各种sql操作,当然走的肯定是tcp协议. 非交互式操作:就是你在你的项目中进行程序调用.比如一边是tom ...

  4. Mysql的连接状态

    对应mysql的连接,任何时刻都有一个状态.表示mysql当前正在做什么. command里面的状态: sleep:线程正在等待客户发送新的请求. query:正在执行查询或者正在将结果发送客户端 这 ...

  5. PAIP.MYSQL SLEEP 连接太多解决

    PAIP.MYSQL SLEEP 连接太多解决 作者Attilax  艾龙,  EMAIL:1466519819@qq.com  来源:attilax的专栏 地址:http://blog.csdn.n ...

  6. javaweb回顾第六篇谈一谈Servlet线程安全问题

    前言:前面说了很多关于Servlet的一些基础知识,这一篇主要说一下关于Servlet的线程安全问题. 1:多线程的Servlet模型 要想弄清Servlet线程安全我们必须先要明白Servlet实例 ...

  7. MySQL服务器的线程数查看方法

    mysql重启命令:/etc/init.d/mysql restart MySQL服务器的线程数需要在一个合理的范围之内,这样才能保证MySQL服务器健康平稳地运行.Threads_created表示 ...

  8. MySQL MySql连接数与线程池

    MySql连接数与线程池 by:授客 QQ:1033553122 连接数 1.  查看允许的最大并发连接数 SHOW VARIABLES LIKE 'max_connections'; 2.  修改最 ...

  9. 谈谈MySQL无法连接的原因和分析方法

    [可能的原因] MySQL无法连接的原因有很多,比如: 1.数据库的请求量突增,实例连接数超过max_connections,或用户连接数超过max_user_connections, 这种情况连接时 ...

随机推荐

  1. C#的常用类

    BitConverter类:用于将源类型转换成字节数组,或者将字节数组转换成目标类型.在解决不同设备之间产生的大小端问题时,经常使用. Convert类:用于基本数据类型(包括Boolean/Byte ...

  2. 使用 Solr 构建企业级搜索服务器

    最近因项目需要一个全文搜索引擎服务, 在考察了Lucene及Solr后,我们选择了Solr. 本文简要记录了基于Solr搭建一个企业搜索服务器的过程.网上的资料太多千篇一律,也可能版本不同,总之在参照 ...

  3. MyBatis之Mapper XML 文件详解(三)-Result Maps

    resultMap 元素是 MyBatis 中最重要最强大的元素.它就是让你远离 90%的需要从结果 集中取出数据的 JDBC 代码的那个东西, 而且在一些情形下允许你做一些 JDBC 不支持的事 情 ...

  4. Oracle中order by case 用法

    select * from ly_familyinformation ' ' order by case when relation = '购房人/申请人' then when relation = ...

  5. 第三天-零基础学习python

    1.回忆.列表方法,append(),extend(),insert() 2.列表获取元素: >>> member = ['HU','YU','HUYAN','HUJIAMU']   ...

  6. oracle静默安装

    RHEL6+oracle11.2 无界面化命令安装如下: 1.所需安装软件包检查: yum install binutils-2.* compat-libcap1* compat-libstdc++- ...

  7. 最优贸易(tarjan,spfa)

    题目描述 C国有n个大城市和m 条道路,每条道路连接这 n个城市中的某两个城市.任意两个城市之间最多只有一条道路直接相连.这 m 条道路中有一部分为单向通行的道路,一部分为双向通行的道路,双向通行的道 ...

  8. ubnutu 安装protocol buffer

    工作中需要使用protocol buffer,需要编译出protocol buffer的动态链接库,然后在别的makefile中链接它, 我的环境是ubnutu16.04,64bit,使用的proto ...

  9. 使用泛型与不使用泛型的Map的遍历

    https://www.cnblogs.com/fqfanqi/p/6187085.html

  10. Java性能优化的50个细节

    在JAVA程序中,性能问题的大部分原因并不在于JAVA语言,而是程序本身.养成良好的编码习惯非常重要,能够显著地提升程序性能. 1. 尽量在合适的场合使用单例 使用单例可以减轻加载的负担,缩短加载的时 ...