1

我需要同步一个mysql查询,所以只有一个用户可以同时访问指定的部分。我试过synchronized(){}了,但这不起作用。用户可以同时访问该方法。这是一个使用tomcat6的jsp web应用程序。我需要这个,因为当太多用户同时运行查询时,网络服务器会崩溃。

String sql = "SELECT * FROM products;"
ResultSet rs;

//This block should be synchronized
Statement s = con.createStatement();
rs = s.excecuteQuery(sql);

while (rs.next()) {
// do some stuff..
}

谢谢你的帮助。

编辑:我如何尝试同步

public class connect {

public static String URL = "url";
public static String USER = "root";
public static String PASSWORD = "password";
private Object lock = new Object();

public void getData() {

    Connection con;

    try {
        con = DriverManager.getConnection(URL, USER, PASSWORD);
        String sql = "SELECT * FROM products;";
        ResultSet rs;

        //This block should be synchronized
        synchronized(lock) {
            Statement s = con.createStatement();
            rs = s.executeQuery(sql);

            while (rs.next()) {
            // do some stuff..
            }
        }
    } catch (SQLException e) {
        e.printStackTrace();
    }
}
}

我认为该对象lock应该存储在服务器上。但是这样做的正确方法是什么?

4

5 回答 5

1

lock如果正在处理的所有请求的对象都相同,则您的代码是可以的。

你怎么能弄明白?如果connect为正在处理的每个请求创建一个新类,则该类的每个实例都有不同的lock,并且同步块可以由不同的实例并发执行。

如果您只有一个connect类的实例,那么您只有一个实例,lock并且您确定没有两个线程可以同时执行同步块。

但是,即使您只有一个类的实例,connect如果重构代码创建了多个此类的实例,也很容易破坏同步。如果要确保此代码为所有线程锁定,则必须将锁定对象声明为静态:

static final Object LOCK = new Object();

现在您可以确定 JVM 中只有一个LOCK

您还必须记住,如果您的应用程序在集群中运行,那么 java 同步将不起作用,因为您有多个 JVM 运行同一个应用程序。请查看此问题以获取有关该主题的更多详细信息。

顺便说一句,尝试遵循类命名约定。类名应以大写字母开头,因此将您的类重命名为Connect.

于 2013-06-07T10:12:19.037 回答
1

你为什么不只使用单例并同步连接,或者在方法上同步

public class MyConnection {

    private Connection mConn;

    public static synchronized Connection getConnection() {
    if(mConn == null){
     mConn = createNewConnection();//your create method
    }
    return mConn;
    }

}
于 2013-06-25T03:38:02.207 回答
0

我不知道您如何同步该方法。但除非包含该方法的类是单例,否则它将无法工作。

好吧,要么是单例,要么您用于锁定该方法的对象必须是这样才能工作。

如果您只是简单地同步方法,类的多个实例将阻碍您的意图。

但在我看来,你的架构有问题。你在使用某种连接管理器吗?

于 2013-06-07T09:10:51.363 回答
0

如果您使用的是 DBCP,那么只需maxActive通过 defulat 配置属性 100。试图获得超过限制的连接的线程将被阻止。

于 2013-06-07T09:13:13.740 回答
0

我的代码的另一部分有错误的查询语句。如果执行此查询,它会执行类似的操作SELECT * FROM TABLE,这会将我的 mysql 服务器关闭。现在我已经修复它并且不必限制数据库访问。谢谢你们的帮助!

于 2013-06-26T05:57:01.590 回答