0

次のようなクラスがある場合:

class MultiThreadEg {

private Member member;

public Integer aMethod() {
    ..............
    ..............
}

public String aThread() {
    ...............
    member.memberMethod(.....);
    Payment py = member.payment();
    py.processPayment();
    ...........................
}

}

aThread()が新しいスレッドであると仮定すると、共有メンバー オブジェクトに同時に多数のスレッドがアクセスすると (次のアクセス ルールで) 問題が発生するでしょうか?

Rule 1 : ONLY reading, no writing to the object(member).
Rule 2 : For all the objects that need some manipulation(writing/modification), a copy of the original object will be created.

例: payment()メソッドでは、次のようにします。

public class Member {

private Payment memPay;

public payment() {
   Payment py = new Payment(this.memPay);//Class's Object copy constructor will be called.
   return py;
}

}

私の懸念は、「書き込み」用にオブジェクトのコピーを作成しても (メソッドpayment()のように)、同時にあまりにも多くのスレッドがメンバーオブジェクトにアクセスすると、いくつかの不一致が生じることです。

事実は何ですか?この実装はすべての場合 (0 以上の同時アクセス) で信頼できますか? お知らせ下さい。ありがとう。

4

2 に答える 2

1

ReentrantReadWriteLockを使用するだけで済みます。そうすれば、問題なく複数のスレッドを同時に読み取ることができますが、データの変更が許可されるのは1つだけです。そして、Javaが並行性を処理します。

 ReadWriteLock rwl = new ReentrantReadWriteLock();
 Lock readLock = rwl.readLock;
 Lock writeLock = rwl.writeLock;

 public void read() {

    rwl.readLock.lock();
    try {
       // Read as much as you want.
    } finally {
       rwl.readlock.unlock();
    }
 }

 public void writeSomething() {
    rwl.writeLock.lock();
    try {
       // Modify anything you want
    } finally {
       rwl.writeLock.unlock();
    }
 }

開始する前にロックが取得されていることを保証するために、tryブロックが開始する前にlock()を実行する必要があることに注意してください。また、finally句にunlock()を配置すると、try内で何が起こっても(早期リターン、例外がスローされるなど)、ロックが解放されることが保証されます。

于 2013-02-07T07:55:51.123 に答える
0

memPayへの更新がmemPayの内容(memPay.amount + = 100など)に依存する場合は、更新時に他のスレッドへのアクセスをブロックする必要があります。これは次のようになります。

mutual exclusion block start
get copy
update copy
publish copy
mutual exclusion block end

そうしないと、2つのスレッドが同時にmemPayオブジェクトの更新を開始したときに、更新が失われる可能性があります。

于 2013-02-07T07:38:09.180 に答える