java - 同步是否锁定结果集对象?

标签 java multithreading jdbc resultset

我正在尝试对结果集进行多线程处理。我想确保每当我在多个线程之一中调用 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/

相关文章:

.net - 在 .NET 中的多线程上快速、高效地处理 HTTP 请求

java - 在 Java 中为给定的结果集生成 MySQL 查询

java - 连接 mysql 服务器失败

java - 纹理添加黑色和白线

java - Java 中二维 int 数组优化的洪水填充

java - 我可以同步控制变量的读取吗?

c# - 如何将 winform 子窗体动态嵌入到主 winform 的选项卡控件中?

java - 如何从JDBC+postgreSql时间戳获取UTC时间戳?

java正则表达式插入字符作为特定索引位置

c# - RSA读取公钥