Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/382.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么锁更改会对JDBC性能产生如此大的影响?_Java_Multithreading_Jdbc - Fatal编程技术网

Java 为什么锁更改会对JDBC性能产生如此大的影响?

Java 为什么锁更改会对JDBC性能产生如此大的影响?,java,multithreading,jdbc,Java,Multithreading,Jdbc,我正在编写一个用于大型多线程应用程序的数据库连接池,该应用程序是按照jdk4标准编写的,使用下面的代码,我可以在0.4秒内通过LAN查询mysql数据库1000次 synchronized(lockA) { if(free.size() > 0) { c = (Connection) free.removeFirst(); } if(c == null) { c = DriverManager.getConnection(query

我正在编写一个用于大型多线程应用程序的数据库连接池,该应用程序是按照jdk4标准编写的,使用下面的代码,我可以在0.4秒内通过LAN查询mysql数据库1000次

synchronized(lockA) {
    if(free.size() > 0) {
        c = (Connection) free.removeFirst();
    }

    if(c == null) {
        c = DriverManager.getConnection(query, name, passw);
    }
}
在这里,lockA保护自由列表(LinkedList),它用于修改和访问列表。将getConnection移出此锁并移入其自己的受保护块是有意义的。getConnection需要被锁保护,因为它在某些地方不是线程安全的

因此,如果我将其更改为DriverManager和列表由单独的锁保护,就像这样

synchronized(lockA) {
    if(free.size() > 0) {
        c = (Connection) free.removeFirst();
    }
}

if(c == null) {
    synchronized(lockB) {
        c = DriverManager.getConnection(query, name, passw);
    }
}
我得到了连续的缓存未命中(C为null),因此性能降低,执行相同的查询需要4秒,而这需要0.4秒

为什么会这样

编辑:

我已经解决了这个问题,当创建太多连接时,功能块的方式会产生问题

这就是在函数开始时发生的事情

synchronized(waitLocK) {
    try {
        while(count >= limit) {
            waitLock.wait();
        } 
    } catch (InterruptedException e) {
    }
}
当连接被释放时,waitLock被释放。但是这里发生的是,在创建连接的代码块之后,count变量(volatile)增加

这具有打开门的效果,因为当1000个线程试图通过等待测试时,它们都通过了,因为计数仍然为0,然后重载getConnection()


尝试后将count++移动到be可以解决此问题。

代码的第二种形式允许无限数量的线程同时请求与数据库的连接,其中第一种形式一次只允许一个线程请求新连接

在用Java编写并发代码时,我有一个简单的规则要遵循:

如果您的代码中有synchronized关键字,那么它可能是错误的,并且会以微妙和不可预测的方式失败

别开玩笑了,你需要仔细考虑一下为什么不能用标准并发类实现你想要的并发结果

skaffman的评论是正确的——您确实不想实现连接池。选择任何一个可用的实现

假设这不是一个连接池。为什么使用synchronize+LinkedList而不是ConcurrentLinkedQueue?您的逻辑尝试从列表中获取连接;如果没有可用的连接,它会创建一个新的连接(可能,调用方在处理完后会释放回列表)


如果您还没有读过的话,这是一本很棒的书。

第二种形式的代码允许无限数量的线程同时请求与数据库的连接,其中第一种形式一次只允许一个线程请求新的连接

在用Java编写并发代码时,我有一个简单的规则要遵循:

如果您的代码中有synchronized关键字,那么它可能是错误的,并且会以微妙和不可预测的方式失败

别开玩笑了,你需要仔细考虑一下为什么不能用标准并发类实现你想要的并发结果

skaffman的评论是正确的——您确实不想实现连接池。选择任何一个可用的实现

假设这不是一个连接池。为什么使用synchronize+LinkedList而不是ConcurrentLinkedQueue?您的逻辑尝试从列表中获取连接;如果没有可用的连接,它会创建一个新的连接(可能,调用方在处理完后会释放回列表)


如果您还没有读过的话,这是一本很棒的书。

很抱歉,是的,C是函数的本地版本。“我正在编写一个数据库连接池”。。。。到底为什么?您可以使用几种开源软件。这是一个很难解决的问题,不要重新发明轮子。@skaffman:特别是因为有一个新的孩子在这座大楼上,它是为多核系统而优化的:对不起,是的,C是函数的本地版本。“我正在写一个数据库连接池”。。。。到底为什么?您可以使用几种开源软件。这是一个很难解决的问题,不要重新发明轮子。@skaffman:特别是因为有一个新的孩子在这个街区,它是为多核系统而优化的: