synchronized是否锁定结果集对象



我正在尝试对结果集进行多线程处理。我想确保每当我在多个线程中的一个线程内调用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定律。如果你有一种情况,你可以阅读结果集并使用结果创建提交给ExecutitorService的任务(正如Peter Lawrey在评论中建议的那样),那么这将更有意义(只要这些任务可以独立工作,不必相互等待)。

我建议创建ResultSet,然后将所有数据复制到DTO(数据传输对象)或DAO(数据访问对象)中。在DTO或DAO上拥有数据后,关闭ResultSet、Statement和Connection。

创建DTO/DAO以按顺序存储记录、字段和解析功能的一个非常简单的结构是:

ArrayList<HashMap<String, Object>> table = new ArrayList<HashMap<String, Object>>();
HashMap<String, Object> record = new HashMap<String, Object>();
String field1 = "something";
Integer field2 = new Integer(45);
record.put("field1", field1);
record.put ("field2", field2);
table.add(record);

您可以(可能也应该)自动化并使DTO/DAO足够灵活,可以在任何表中使用相同的类,而不需要硬代码或固定名称。

请记住,您将需要创建一个包装器和用于存储/读取数据的方法,并且这些方法应该是线程安全的。

请记住,只有当您有足够的内存来存储ResultSet的所有记录时,此设计才有效。

相关内容

  • 没有找到相关文章

最新更新