这些简短的方法必须在Java中同步吗?

时间:2015-03-21 13:25:20

标签: java multithreading synchronized

考虑遵循静态助手

public class DbUtil {

    private static final Logger logger = LogManager.getLogger(DbUtil.class);

    public static void closeAll(ResultSet rs, Statement stmt, Connection conn) {
        close(rs);
        close(stmt);
        close(conn);
    }

    public static void close(Connection connection) {
        if (connection != null) {
            try {
                connection.close();
            } catch (SQLException e) {
                logger.error(null, e);
            }
        }
    }

    public static void close(Statement statement) {
        if (statement != null) {
            try {
                statement.close();
            } catch (SQLException e) {
                logger.error(null, e);
            }
        }
    }

    public static void close(ResultSet resultSet) {
        if (resultSet != null) {
            try {
                resultSet.close();
            } catch (SQLException e) {
                logger.error(null, e);
            }
        }
    }

    public static void closeAny(Object o) {
        if(o == null) return;

        try {
            if (o instanceof Statement) {
                Statement stmt = (Statement) o;
                stmt.close();
            } else if(o instanceof Connection) {
                Connection conn = (Connection) o;
                conn.close();
            } else if(o instanceof ResultSet) {
                ResultSet rs = (ResultSet) o;
                rs.close();
            } else {
                logger.warn("Unknown object type");
            }
        } catch(SQLException e) {
            logger.error(null, e);
        }
    }

}

这个类可以被多个线程使用。必须同步所有方法或其中一些方法,为什么?

实际上我不确定是否有可能在resultSet != null检查后,一个线程的形式参数被另一个线程的不同对象实例更改,因此另一个ResultSet,Statement或Connection被关闭(如果方法不同步)。

2 个答案:

答案 0 :(得分:2)

  

我不确定是否有可能在resultSet!= null之后检查一个线程正式参数被另一个线程用不同的对象实例更改

不,方法参数与局部变量具有相同的语义。它们是单个方法调用的私有,不能被任何其他线程变异。

如果每个调用线程都使用来自其自己的线程本地连接的对象,那么就没有问题。在这种情况下,您的方法不会共享任何状态。

答案 1 :(得分:1)

从Java 7开始,您应该使用更简单的代码:

public class DbUtil {

    private static final Logger logger = LogManager.getLogger(DbUtil.class);

    public static void closeAll(AutoCloseable... resources) {
        for (AutoCloseable resource: resources)
            close(resource);
    }

    public static void close(AutoCloseable resource) {
        if (resource != null) {
            try {
                resource.close();
            } catch (Exception e) {
                logger.error(null, e);
            }
        }
    }
}