我正在尝试对结果集进行多线程处理。我想确保每当我在多个线程之一中调用 next()
时,所有其他线程都被锁定。这很重要,因为如果许多线程同时调用 next()
方法,这将导致跳过行。这是我所做的
public class MainClass {
private static ResultSet rs;
public static void main (String [] args) {
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
runWhile();
}});
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
runWhile();
}});
thread1.start();
thread2.start();
thread1.join();
thread2.join();
System.exit(0);
}
private static void runWhile () {
String username = null;
while ((username = getUsername()) != null) {
// Use username to complete my logic
}
}
/**
* This method locks ResultSet rs until the String username is retrieved.
* This prevents skipping the rows
* @return
* @throws SQLException
*/
private synchronized static String getUsername() throws SQLException {
if(rs.next()) {
return rs.getString(1).trim();
}
else
return null;
}
}
这是使用synchronized
的正确方法吗?它是否锁定ResutSet并确保其他线程不会干扰?
这是一个好方法吗?
最佳答案
不应在线程之间共享 JDBC 对象。这适用于连接、语句和结果集。这里最好的情况是 JDBC 供应商遵循规范并执行内部锁定,这样您就可以解决这个问题,在这种情况下,所有线程仍在尝试获取相同的锁,并且一次只有一个线程可以取得进展。这比使用单个线程要慢,因为除了从数据库读取数据执行相同的工作之外,管理所有线程还会产生额外的开销。
(驱动程序完成的锁定可能是为了驱动程序的利益,因此提供商不必处理因用户滥用其软件而引起的竞争条件的错误报告。它确实锁定并不一定意味着软件应该实际上被多个线程使用。)
当线程可以同时取得进展时,多线程就可以工作,请参阅 Amdahl's Law 。如果您遇到这样的情况,您可以读取 ResultSet 并使用结果来创建提交给 ExecutorService 的任务(正如 Peter Lawrey 在评论中建议的那样),那么这会更有意义(只要这些任务可以独立工作并且不不必互相等待)。
关于java - 同步是否锁定结果集对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37552279/