2017-12-22 6 views
0

私は2つの方法を持っており、それぞれが異なるThreadによって実行されています。2つのメソッドの同時実行を避けるにはどうすればよいですか?

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); 
} 

しかし、それは私がプロジェクト全体で使用されるすべてのコードを変更する必要があります意味:私の心に来る

一つの解決策は、次のようです。それを行うクリーナーの方法はありますか?

+2

あなたの最初のスニペットだけで結構です(両方のスレッドが自分のクエリを実行するために同じオブジェクトを使用して)。あなたは同期が何をしていると思いますか? –

+2

しかし、リレーショナルデータベースには**同時クエリーを安全な方法で実行できるようにするACIDトランザクションがあります。あなたはそれらを同期しません。とにかく、いくつかのクライアントが同じデータベースをターゲットとするとすぐには動作しません。 –

答えて

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を使用するために、おそらく良いでしょう。 1は読み取りおよび1つの書き込みであるため、

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.

+0

ありがとうございますが、抽象的であるため、 'ReadWriteLock()'をインスタンス化できないというエラーが表示されます。おそらく私は間違ったライブラリをインポートしていますか? – Robb1

+0

'ReentrantReadWriteLock'を使うと、' ReadWriteLock'インターフェースの実装です。 – user6690200

+1

@ Robb1 javadoc(https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/ReadWriteLock.html)を使用する方法を学ぶ必要があります。それには、最初は「すべての既知の実装クラス」と呼ばれるセクションがあります。しかし、再び、これは役に立たないのですか?データベースは、並行トランザクションをサポートします。 –

関連する問題