- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
首先,我在线程安全编程方面经验不多。
我有一个MySQL类,我想在多个线程中使用一个实例来防止主线程中的代码阻塞。我阅读了有关连接池的信息,但我希望它尽可能简单。
这是我的 MySQL 类:
package com.vanillage.bukkitutils.mysql;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
public class MySQL {
private final String host;
private final int port;
private final String database;
private final String user;
private final String password;
private Connection connection;
public MySQL(String host, int port, String database, String user, String password) {
if (host == null) {
//TODO
}
if (database == null) {
//TODO
}
if (user == null) {
//TODO
}
if (password == null) {
//TODO
}
this.host = host;
this.port = port;
this.database = database;
this.user = user;
this.password = password;
}
public String getHost() {
return host;
}
public int getPort() {
return port;
}
public String getDatabase() {
return database;
}
public String getUser() {
return user;
}
public String getPassword() {
return password;
}
public Connection getConnection() {
return connection;
}
public synchronized void connect() throws SQLException {
connection = DriverManager.getConnection("jdbc:mysql://" + host + ":" + port + "/" + database + "?autoReconnect=true", user, password);
}
public synchronized void checkConnection(int timeout) throws SQLException {
if (connection == null) {
connect();
} else {
boolean connectionValid = false;
try {
connectionValid = connection.isValid(timeout);
} catch (SQLException e) {
e.printStackTrace();
connect();
connectionValid = true;
}
if (!connectionValid) {
connect();
}
}
}
public synchronized ResultSet query(String query) throws SQLException {
return connection.prepareStatement(query).executeQuery();
}
public synchronized boolean update(String query) throws SQLException {
return connection.prepareStatement(query).execute();
}
public synchronized void close() throws SQLException {
if (connection != null) {
connection.close();
connection = null;
}
}
public synchronized boolean hasConnection(boolean checkOpen, boolean checkValid, int timeout) throws SQLException {
return connection != null && (!checkOpen || !connection.isClosed()) && (!checkValid || connection.isValid(timeout));
}
@Override
public String toString() {
return host + ":" + port + ", " + database + ", " + user + ", " + password;
}
}
是否可以使用 synchronized 关键字使我的 MySQL 类线程安全,因为我已经在上面的代码中使用了它?
我在不同线程中使用此类:
try {
mySQL.checkConnection(0);
try {
ResultSet resultSet = mySQL.query("SELECT * FROM Example");
if (resultSet.next()) {
System.out.println(resultSet.getString("Example"));
}
} catch (SQLException e) {
System.out.println("Error while executing query: " + e.getMessage());
}
} catch (SQLException e) {
System.out.println("Could not create a valid connection: " + e.getMessage());
}
我的问题:它是线程安全的吗?
编辑:
package testprogramm;
import java.beans.PropertyVetoException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
import com.mchange.v2.c3p0.ComboPooledDataSource;
public class TestProgramm {
private static final Scanner scanner = new Scanner(System.in);
private static Map<String, ComboPooledDataSource> dataSources = new HashMap<>();
public static void main(String[] args) {
//setup connections
ComboPooledDataSource testDataSource = new ComboPooledDataSource();
try {
testDataSource.setDriverClass("com.mysql.jdbc.Driver");
} catch (PropertyVetoException e) {
e.printStackTrace();
}
testDataSource.setJdbcUrl("jdbc:mysql://localhost:3306/database");
testDataSource.setUser("user");
testDataSource.setPassword("password");
dataSources.put("test", testDataSource);
while (true) {
String line = scanner.nextLine();
ComboPooledDataSource dataSource = dataSources.get(line);
if (dataSource != null) {
new Thread(new Runnable() {
ComboPooledDataSource dataSource = null;
public Runnable init(ComboPooledDataSource dataSource) {
this.dataSource = dataSource;
return this;
}
@Override
public void run() {
try {
Connection connection = dataSource.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM Example");
ResultSet resultSet = preparedStatement.executeQuery();
int i = 0;
while (resultSet.next()) {
i ++;
}
resultSet.close();//TODO: move to finally clause with null check and try/catch
preparedStatement.close();
connection.close();
System.out.println(i + " entries");
} catch (SQLException e) {
System.out.println("Error while executing statement: " + e.getMessage());
}
}
}.init(dataSource)).start();
} else {
System.out.println("No such connection");
}
}
}
}
最佳答案
您的问题:它是线程安全的吗?
我的回答:不,不是。
打破它的最简单方法:让您的线程之一调用 mySQL.getConnection().close();
除此之外:大多数连接根本不喜欢并行语句。那应该是什么交易范围呢?
您应该认真地考虑使用连接池。我最喜欢的选择是 c3p0。参见 http://www.mchange.com/projects/c3p0/#quickstart一个快速入门的例子。
确保安全
您无需传递 MySQL
实例,而是创建并配置 ComboPooledDataSource
(或您要使用的任何其他数据源)。然后在您的类中,从该池中获取一个 Connection
,执行您的 SQL 语句,然后关闭它。最方便的方法是使用 Java 7 引入的 try-with-resource:
try(Connection con = pool.getConnection();
PreparedStatement ps = con.prepareStatement("SELECT * FROM whatever");
ResultSet rs = ps.executeQuery()) {
while(rs.next()) {
//handle resultset
}
}
关于您现有类(class)的更多信息
如果你这样做,你将无法清理大量的 Statements
public synchronized ResultSet query(String query) throws SQLException {
//Statement never closed
return connection.prepareStatement(query).executeQuery();
}
public synchronized boolean update(String query) throws SQLException {
//Statement never closed
return connection.prepareStatement(query).execute();
}
关于Java 异步 MySQL 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34117164/
我正在编写一个具有以下签名的 Java 方法。 void Logger(Method method, Object[] args); 如果一个方法(例如 ABC() )调用此方法 Logger,它应该
我是 Java 新手。 我的问题是我的 Java 程序找不到我试图用作的图像文件一个 JButton。 (目前这段代码什么也没做,因为我只是得到了想要的外观第一的)。这是我的主课 代码: packag
好的,今天我在接受采访,我已经编写 Java 代码多年了。采访中说“Java 垃圾收集是一个棘手的问题,我有几个 friend 一直在努力弄清楚。你在这方面做得怎么样?”。她是想骗我吗?还是我的一生都
我的 friend 给了我一个谜语让我解开。它是这样的: There are 100 people. Each one of them, in his turn, does the following
如果我将使用 Java 5 代码的应用程序编译成字节码,生成的 .class 文件是否能够在 Java 1.4 下运行? 如果后者可以工作并且我正在尝试在我的 Java 1.4 应用程序中使用 Jav
有关于why Java doesn't support unsigned types的问题以及一些关于处理无符号类型的问题。我做了一些搜索,似乎 Scala 也不支持无符号数据类型。限制是Java和S
我只是想知道在一个 java 版本中生成的字节码是否可以在其他 java 版本上运行 最佳答案 通常,字节码无需修改即可在 较新 版本的 Java 上运行。它不会在旧版本上运行,除非您使用特殊参数 (
我有一个关于在命令提示符下执行 java 程序的基本问题。 在某些机器上我们需要指定 -cp 。 (类路径)同时执行java程序 (test为java文件名与.class文件存在于同一目录下) jav
我已经阅读 StackOverflow 有一段时间了,现在我才鼓起勇气提出问题。我今年 20 岁,目前在我的家乡(罗马尼亚克卢日-纳波卡)就读 IT 大学。足以介绍:D。 基本上,我有一家提供簿记应用
我有 public JSONObject parseXML(String xml) { JSONObject jsonObject = XML.toJSONObject(xml); r
我已经在 Java 中实现了带有动态类型的简单解释语言。不幸的是我遇到了以下问题。测试时如下代码: def main() { def ks = Map[[1, 2]].keySet()
一直提示输入 1 到 10 的数字 - 结果应将 st、rd、th 和 nd 添加到数字中。编写一个程序,提示用户输入 1 到 10 之间的任意整数,然后以序数形式显示该整数并附加后缀。 public
我有这个 DownloadFile.java 并按预期下载该文件: import java.io.*; import java.net.URL; public class DownloadFile {
我想在 GUI 上添加延迟。我放置了 2 个 for 循环,然后重新绘制了一个标签,但这 2 个 for 循环一个接一个地执行,并且标签被重新绘制到最后一个。 我能做什么? for(int i=0;
我正在对对象 Student 的列表项进行一些测试,但是我更喜欢在 java 类对象中创建硬编码列表,然后从那里提取数据,而不是连接到数据库并在结果集中选择记录。然而,自从我这样做以来已经很长时间了,
我知道对象创建分为三个部分: 声明 实例化 初始化 classA{} classB extends classA{} classA obj = new classB(1,1); 实例化 它必须使用
我有兴趣使用 GPRS 构建车辆跟踪系统。但是,我有一些问题要问以前做过此操作的人: GPRS 是最好的技术吗?人们意识到任何问题吗? 我计划使用 Java/Java EE - 有更好的技术吗? 如果
我可以通过递归方法反转数组,例如:数组={1,2,3,4,5} 数组结果={5,4,3,2,1}但我的结果是相同的数组,我不知道为什么,请帮助我。 public class Recursion { p
有这样的标准方式吗? 包括 Java源代码-测试代码- Ant 或 Maven联合单元持续集成(可能是巡航控制)ClearCase 版本控制工具部署到应用服务器 最后我希望有一个自动构建和集成环境。
我什至不知道这是否可能,我非常怀疑它是否可能,但如果可以,您能告诉我怎么做吗?我只是想知道如何从打印机打印一些文本。 有什么想法吗? 最佳答案 这里有更简单的事情。 import javax.swin
我是一名优秀的程序员,十分优秀!