java - 使用 java Lock 和 Condition 对象

标签 java multithreading synchronization locking synchronized

我在下面构建了这个数据库对象。

我希望方法更新和查询为: 1.以多线程方式工作(意味着2个线程可以同时访问它们——synchronized会阻止什么——这就是为什么我不能将它添加到单一方法中)。 2.如果一个线程已开始打开数据库,而第二个线程(在它之后启动)正在尝试使用该数据库 - 我不希望出现第二个线程在数据库尚未打开时访问数据库的情况。换句话说 - 我希望它一般是多线程的,但当 1 个线程第一次打开数据库时线程安全(原子)。

谢谢, 下面的类是我需要插入逻辑的地方(更具体地说 - 查询和更新方法)。

public class SingeltonDB {
    private static DBconnImpl db = null;
    private static SingeltonDB singalDb = null;

    private SingeltonDB(String username, String password) {
        db = new DBconnImpl();
    }

    public static boolean isOpen() {
        return (db != null);
    }

    public synchronized static SingeltonDB getInstance(String username,
            String password) throws Exception {
        if (db != null) {
            throw (new Exception("The database is  open"));
        } else {
            System.out.println("The database is now open");
            singalDb = new SingeltonDB(username, password);
        }
        db.connect(username, password);
        System.out.println("The database was connected");
        return singalDb;
    }

    public synchronized static SingeltonDB getInstance() throws Exception {
        if (db == null) {
            throw (new Exception("The database is not open"));
        }

        return singalDb;
    }

    public void create(String tableName) throws Exception {
        db.create(tableName);
    }

    public  User query(String tableName, int rowID) throws Exception {
        if (db == null) {
            System.out.println("Error: the database is not open");
            return null;
        }
        return (db.query(tableName, rowID));
    }

    public  void update(String tableName, User user) throws Exception {
        if (db == null) {
            System.out.println("Error: the database is not open");
            return;
        }
        db.update(tableName, user);
    }

}

最佳答案

我会将 connect 调用从 getInstance 静态方法移至 SingeltonDB 构造函数。这将保证每当您获得对静态数据库字段的引用时都会打开数据库。我还将向所有非静态方法添加 db == null 检查。

public class SingeltonDB {
    private static DBconnImpl db = null;
    private static SingeltonDB singalDb = null;

    private SingeltonDB(String username, String password) {
        db = new DBconnImpl();
        db.connect(username, password);
        System.out.println("The database was connected");
    }

    public static boolean isOpen() {
        return (db != null);
    }

    public synchronized static SingeltonDB getInstance(String username,
            String password) throws Exception {
        if (db != null) {
            throw (new Exception("The database is  open"));
        } else {
            System.out.println("The database is now open");
            singalDb = new SingeltonDB(username, password);
        }
        return singalDb;
    }

    public synchronized static SingeltonDB getInstance() throws Exception {
        if (db == null) {
            throw (new Exception("The database is not open"));
        }

        return singalDb;
    }

    private static void checkDbOpened() throws Exception {
        if (db == null) {
            throw new Exception("The database is not open");
        }
    }

    public void create(String tableName) throws Exception {
        checkDbOpened();
        db.create(tableName);
    }

    public  User query(String tableName, int rowID) throws Exception {
        checkDbOpened();
        return (db.query(tableName, rowID));
    }

    public  void update(String tableName, User user) throws Exception {
        checkDbOpened();
        db.update(tableName, user);
    }

}

这是一个更新的单例,它允许您确定是否创建了表

public class SingeltonDB {
    private static DBconnImpl db = null;
    private static SingeltonDB singalDb = null;
    private static ConcurrentSkipListSet<String> tableNames = new ConcurrentSkipListSet<String>();

    private SingeltonDB(String username, String password) {
        db = new DBconnImpl();
        db.connect(username, password);
        System.out.println("The database was connected");
    }

    public static boolean isOpen() {
        return (db != null);
    }

    public synchronized static SingeltonDB getInstance(String username,
            String password) throws Exception {
        if (db != null) {
            throw (new Exception("The database is  open"));
        } else {
            System.out.println("The database is now open");
            singalDb = new SingeltonDB(username, password);
        }
        return singalDb;
    }

    public synchronized static SingeltonDB getInstance() throws Exception {
        if (db == null) {
            throw (new Exception("The database is not open"));
        }

        return singalDb;
    }

    private static void checkDbOpened() throws Exception {
        if (db == null) {
            throw new Exception("The database is not open");
        }
    }

    private static void checkForTable(String tableName) {
        if (tableNames.add(tableName)) {
           db.create(tableName);
        }
    }

    public void create(String tableName) throws Exception {
        checkDbOpened();
        checkForTable(tableName);
    }

    public  User query(String tableName, int rowID) throws Exception {
        checkDbOpened();
        checkForTable(tableName);
        return (db.query(tableName, rowID));
    }

    public  void update(String tableName, User user) throws Exception {
        checkDbOpened();
        checkForTable(tableName);
        db.update(tableName, user);
    }

}

checkForTable 函数将确定给定的 tableName 是否已创建。如果不是,它将创建该表。此更新将确保该表是在使用之前创建的。此代码的问题在于,它不能跨进程工作,而只能在单个进程中工作,除非 db 类知道如何管理跨进程边界创建的表。

关于java - 使用 java Lock 和 Condition 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27425705/

相关文章:

java - 无法实例化类型 Lock

java - Vector 与 SynchronizedList 性能

c# - 同步两个枚举

java - MBeanExporter 和 bean 的条件加载

java - JDialog 和 JFrame 以及新实例

java - 删除重复次数超过n次的元素

c# - 强制某些代码始终在同一线程上运行

java - 设计模式: Partial Object creation of unknown instance members at runtime

c# - 如何取消和重新启动 C# 任务

visual-studio - CreateThread()错误