如何避免两种方法的并发执行?

时间:2017-12-22 07:49:45

标签: java multithreading locking

我有两个synchronized方法,每个方法都由不同的Thread执行。

public synchronized ResultSet dbExecuteQuery(String queryStmt);

public synchronized void dbExecuteUpdate(String queryStmt);

如何确保执行不会“重叠”?

我想到的一个解决方案如下:

public synchronized ResultSet dbExecute(String queryStmt, boolean isUpdate) {
if (isUpdate) {
    dbExecuteUpdate(queryStmt);
    return null;
} else
    return dbExecuteQuery(queryStmt);
}

但这意味着我必须更改整个项目中使用的所有代码。有更清洁的方法吗?

1 个答案:

答案 0 :(得分:2)

您可以添加专用同步对象:

class YourClass {
    Object syncObject = new Object();
    public ResultSet dbExecuteQuery(String queryStmt) {
        synchronized(syncObject) {
            // your code
        }
    }

    public void dbExecuteUpdate(String queryStmt) {
        synchronized(syncObject) {
            // other code
        }
    }
}

但最好使用ReentrantLock

class YourClass {
    private Lock lock = new ReentrantLock();
    public ResultSet dbExecuteQuery(String queryStmt) {
        lock.lock();
        // your code
        lock.unlock();
    }

    public void dbExecuteUpdate(String queryStmt) {
        lock.lock();
        // other code
        lock.unlock();
    }
}

实际上,由于一个是读取而一个是写入,因此您可能希望使用ReadWriteLock

class YourClass {
    private ReadWriteLock lock = new ReentrantReadWriteLock();
    public ResultSet dbExecuteQuery(String queryStmt) {
        lock.readLock().lock();
        // your code
        lock.readLock()..unlock();
    }

    public void dbExecuteUpdate(String queryStmt) {
        lock.writeLock()..lock();
        // other code
        lock.writeLock().unlock();
    }
}

通过这种方式,您可以同时读取多个线程:

  

The read lock may be held simultaneously by multiple reader threads, so long as there are no writers. The write lock is exclusive.