同步多个方法访问

时间:2013-06-07 09:00:11

标签: java jdbc synchronization

我需要同步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应存储在服务器上。但是这样做的正确方法是什么?

5 个答案:

答案 0 :(得分:1)

如果lock对象对于正在处理的所有请求都相同,则代码正常。

你怎么能搞清楚?如果为正在处理的每个请求创建新的connect类,则此类的每个实例都具有不同的lock,并且synchronized块可以由不同的实例同时执行。

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

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

static final Object LOCK = new Object();

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

您还必须记住,如果您的应用程序在群集中运行,那么Java同步将无法工作,因为您有多个运行相同应用程序的JVM。有关该主题的详细信息,请查看this question

BTW,尝试遵循类命名约定。类名应以大写字母开头,因此将您的类重命名为Connect

答案 1 :(得分:1)

为什么不直接使用单例并同步Connection,或者在方法上同步

public class MyConnection {

    private Connection mConn;

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

}

答案 2 :(得分:0)

我不知道你是如何同步这个方法的。但除非包含该方法的类是单例,否则它将不起作用。

无论是单例还是用于锁定方法的对象都必须能够正常工作。

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

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

答案 3 :(得分:0)

如果您正在使用DBCP,则只需通过defulat配置maxActive属性为100。试图使Connection超过限制的线程将被阻止。

答案 4 :(得分:0)

我的代码的另一部分中有一个错误的查询语句。如果执行了这个查询,它会执行类似SELECT * FROM TABLE的操作,这会导致我的mysql服务器崩溃。现在我修复了它,不必限制db访问。谢谢你的帮助!