java JDBC 和多线程
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/39067373/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
JDBC and Multithreading
提问by fanbondi
I am trying to run few queries using a multithreaded approach, however I think I am doing something wrong because my program takes about five minute to run a simple select statement like
我正在尝试使用多线程方法运行一些查询,但是我认为我做错了什么,因为我的程序需要大约五分钟才能运行一个简单的选择语句,例如
SELECT * FROM TABLE WHERE ID = 123'
My implementation is below and I am using one connection object.
我的实现如下,我正在使用一个连接对象。
In my run method
在我的运行方法中
public void run() {
runQuery(conn, query);
}
runQuery method
运行查询方法
public void runQuery(Connection conn, String queryString){
Statement statement;
try {
statement = conn.createStatement();
ResultSet rs = statement.executeQuery(queryString);
while (rs.next()) {}
} catch (SQLException e) {
e.printStackTrace();
}
}
Finally in the main method, I start the threads using the snippet below.
最后在 main 方法中,我使用下面的代码片段启动线程。
MyThread bmthread = new MyThread(conn, query);
ArrayList<Thread> allThreads = new ArrayList<>();
double start = System.currentTimeMillis();
int numberOfThreads = 1;
for(int i=0; i<=numberOfThreads; i++){
Thread th = new Thread(bmthread);
th.setName("Thread "+i);
System.out.println("Starting Worker "+th.getName());
th.start();
allThreads.add(th);
}
for(Thread t : allThreads){
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
double end = System.currentTimeMillis();
double total = end - start;
System.out.println("Time taken to run threads "+ total);
Update : I am now using separate connection for each thread.
更新:我现在为每个线程使用单独的连接。
ArrayList<Connection> sqlConn = new ArrayList<>();
for(int i =0; i<10; i++){
sqlConn.add(_ut.initiateConnection(windowsAuthURL, driver));
}
loop:
MyThread bmthread = new MyThread(sqlConn.get(i), query);
采纳答案by Francisco Tena
As rohivats and Asaph said, one connection must be used by one and only one thread, that said, consider using a database connection pool. Taking into account that c3p0 and similars are almost abandoned, I would use HirakiCPwhich is really fast and reliable.
正如 rohivats 和 Asaph 所说,一个连接必须由一个且只有一个线程使用,也就是说,考虑使用数据库连接池。考虑到 c3p0 和类似版本几乎被放弃,我会使用HirakiCP,它非常快速可靠。
If you want something very simple you could implement a really simple connection pool using a thread safe collection (such as LinkedList), for example:
如果你想要一些非常简单的东西,你可以使用线程安全集合(例如 LinkedList)来实现一个非常简单的连接池,例如:
public class CutrePool{
String connString;
String user;
String pwd;
static final int INITIAL_CAPACITY = 50;
LinkedList<Connection> pool = new LinkedList<Connection>();
public String getConnString() {
return connString;
}
public String getPwd() {
return pwd;
}
public String getUser() {
return user;
}
public CutrePool(String connString, String user, String pwd) throws SQLException {
this.connString = connString;
for (int i = 0; i < INITIAL_CAPACITY; i++) {
pool.add(DriverManager.getConnection(connString, user, pwd));
}
this.user = user;
this.pwd = pwd;
}
public synchronized Connection getConnection() throws SQLException {
if (pool.isEmpty()) {
pool.add(DriverManager.getConnection(connString, user, pwd));
}
return pool.pop();
}
public synchronized void returnConnection(Connection connection) {
pool.push(connection);
}
}
As you can see getConnection and returnConnection methods are synchronized to be thread safe. Get a connection (conn = pool.getConnection();
) and don't forget to return/free a connection after being used (pool.returnConnection(conn);
)
如您所见, getConnection 和 returnConnection 方法被同步以保证线程安全。获取连接 ( conn = pool.getConnection();
) 并且使用后不要忘记返回/释放连接 ( pool.returnConnection(conn);
)
回答by Asaph
Don't use the same connection object in all threads. Give each thread a dedicated database connection.
不要在所有线程中使用相同的连接对象。给每个线程一个专用的数据库连接。
回答by rohitvats
One Connection
can only execute one query at a time. You need multiple connections available to execute database operations in parallel. Try using a DataSource
with a connection pool, and make each thread request a connection from the pool.
一次Connection
只能执行一个查询。您需要多个连接来并行执行数据库操作。尝试将 aDataSource
与连接池一起使用,并使每个线程从池中请求一个连接。