如何解决使用mutil-thread时,为什么静态代码中的Class.forName会终止进程?
我目前正在学习JDBC。而且,我尝试更新产品信息并同时插入日志。
private void testTransaction() {
try {
// Get Connection
Connection connection = ConnectionUtils.getConnection();
connection.setAutoCommit(false);
// Execute SQL
Product product = new Product(1,4000d);
productService.updateProduct(connection,product);
Log log = new Log(true,"None");
logService.insertLog(connection,log);
// Commit transaction
connection.commit();
} catch (Exception e) {
e.printStackTrace();
} finally {
ConnectionUtils.closeConnection();
}
}
使用单线程时,就可以了。
@Test
public void testMultiThread() {
testTransaction();
}
但是当我使用多线程时,即使启动一个线程,该过程也会自动终止。
@Test
public void testMultiThread() {
for (int i = 0; i < 1; i++) {
new Thread(this::testTransaction).start();
}
}
调试后,我发现是Class.forName()
中的ConnectionUtils
函数导致了这种情况。
public class ConnectionUtils {
static private String url;
static private String driver;
static private String username;
static private String password;
private static Connection connection = null;
private static ThreadLocal<Connection> t = new ThreadLocal<>();
static {
try {
Properties properties = new Properties();
properties.load(new FileReader("src/main/resources/jdbcConnection.properties"));
driver = properties.getProperty("driver");
url = properties.getProperty("url");
username = properties.getProperty("username");
password = properties.getProperty("password");
Class.forName(driver);
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
public static Connection getConnection() {
try {
connection = DriverManager.getConnection(url,username,password);
} catch (Exception e) {
e.printStackTrace();
} finally {
t.set(connection);
}
return connection;
}
}
该过程将在Class.forName()
处终止。我通过在语句之前和之后添加两个打印函数来找到此方法。而且只有前一种作品。
System.out.println("Before");
Class.forName(driver);
System.out.println("After");
控制台仅显示Before
,并且不显示任何异常信息。
我想知道为什么Java多线程会导致这种情况以及如何解决这个问题。
解决方法
这很可能是您的测试方法在其他线程和测试框架没有等待(junit吗?)之前完成的。您需要等待直到线程完成。您应该使用Executors,这更方便。
Measurable max = Data.max(countries) // gives max measure containing object
System.out.println(max.getMeasure()) // prints the max measure value
,
只要测试方法完成,Junit就会终止所有线程。
在您的情况下,测试将在循环结束时完成,而不管是否
testTransaction
已完成。与class.forName
无关,也许只是因为此方法执行时间更长。
您可以检查this answer
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。