use*_*412 5 java multithreading threadpool threadpoolexecutor
假设一个简单的双线程场景的以下伪代码:
我有两个线程,我想将数据插入到不同的表到数据库.在thread1上,我想插入一些表,同时,我想将其他数据插入到线程2. 我的问题是如何/在何处放置connection.close(),如果我将它放在线程1上并执行而thread2仍在处理,反之亦然,如果thread2已完成并关闭连接,但thread1尚未完成.
注意,数据库只是一个例子,它可以是文件,logger ..等等.
class Thread1{
DataBaseConnection connection;
main(){
threadPool = Executors.newFixedThreadPool(1);
connection.open();
if(ThisMightTakeSomeTime)
threadPool.submit(new MyRunnable(connection));
InsertDataToDataBase(Table A, Table B));
connection.Close(); //What if thread2 isn't done yet?
}
}
public class MyRunnable implements Runnable {
MyRunnable(connection){}
@override
void Run() { ...}
void TaskThatMayTakeWhile(){
...get data ...
...Connection.InsertToTables(table X, table Y)
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题是如何/在哪里放置connection.close(),
首先,据我所知,你不应该与2个不同的线程共享一个连接.每个线程都应该拥有自己的数据库连接,可能使用数据库连接池,例如Apache的DBCP.
一旦你有多个连接,我就会让每个线程管理并释放自己的连接回到池中.您应确保在finally块中完成此操作以确保如果存在数据库异常,则仍会释放连接.
如果您被迫让多个线程共享同一个连接,那么他们必须使用它synchronized来确保它们具有对它的独占锁定:
synchronized (connection) {
// use the connection
}
Run Code Online (Sandbox Code Playgroud)
至于何时关闭它,如果它是共享的,你可以有一个共享的使用计数器(可能是AtomicInteger),当计数器变为0时关闭它.或者正如其他人建议你可以使用线程池然后线程池是完成连接.
注意,数据库只是一个例子,它可以是文件,logger ..等等.
就更通用的答案而言,我总是试图反映创建事物的位置.如果一个方法打开流,那么它应该finally关闭流.
public void someMethod() {
InputStream stream = ...
try {
// process the stream here probably by calling other methods
} finally {
// stream should be closed in the same method for parity
stream.close();
}
}
Run Code Online (Sandbox Code Playgroud)
此模式的例外是线程处理程序.那么Thread应该关闭在该流或释放连接finally在的端块run()或call()方法.
public void serverLoopMethod() {
while (weAcceptConnections) {
Connection connection = accept(...);
threadPool.submit(new ConnectionHandler(connection);
}
}
...
private static class ConnectionHandler implements Runnable {
private Connection connection;
public ConnectionHandler(Connection connection) {
this.connection = connection;
}
// run (or call) method executed in another thread
public void run() {
try {
// work with the connection probably by calling other methods
} finally {
// connection is closed at the end of the thread run method
connection.close();
}
}
}
Run Code Online (Sandbox Code Playgroud)