0

一度に実行されるクラス A の複数のインスタンスがあります。

クラス A は、実行中にクラス B の複数のインスタンスを呼び出します。

public Class Main {

    public static void main(String args[] ) {

        A a1 = new A();
        Thread t1 = new Thread(a1);
        t1.start();

        A a2 = new A();
        Thread t2 = new Thread(a2);
        t2.start();
    }
}

Class A implements Runnable {

    public void run() {

        B b1 = new B();
        Thread t11 = new Thread(b1);
        t11.start();

        B b2 = new B();
        Thread t21 = new Thread(b2);
        t21.start();
    }
}

Set Collection を編集するクラス B に「method」という名前のメソッドがあります。その編集は、クラス B の静的ロックに基づいて行われます。

編集-

Class B implements Runnable {

    private final static Object LOCK = new Object();
    private final static Set<T> busyRecords = new HashSet<T>();

    public void waitToWorkOn(final T obj) {
        synchronized(LOCK) {
            while (busyRecords.contains(obj)) {
        LOCK.wait(); //go to sleep
       }
       busyRecords.add(obj);            
    }
    }

    public void doneWith(final T obj) {
        synchronized(LOCK) {
           busyRecords.remove(obj);
      LOCK.notifyAll(); 
    }
    }

    public void mathod(obj)  {

     try{
        waitToWorkOn(obj);

         .. do some work with obj
     }
     finally {
        doneWith(obj);
     }
    }

    public void run() {
        method(getObj())
    }
}

ただし、その Set は、異なる "A" インスタンスからアクセスされる場合、同時実行制御を必要としません。A インスタンス内でのみ、すべての B インスタンスに対してロックする必要があります

つまり、A の 2 つのインスタンスが実行されている場合、それらを待機させてはなりません。しかし、A インスタンス内で 2 つの B オブジェクトが同じ obj を選択すると、LOCK.wait 内で待機する必要があります。

A が B の複数のインスタンスを呼び出すため、LOCK を非静的にすることはできないと思います。

4

1 に答える 1

1

共有コレクションのスレッドセーフなインスタンスを作成し、それを特定の A のすべての B に渡すことができます。

Class A implements Runnable {

    public void run() {

        // create shared set instance scoped to A, and make it thread-safe
        Set col = Collections.synchronizedSet(new HashSet());

        B b1 = new B(col);
        Thread t11 = new Thread(b1);
        t11.start();

        B b2 = new B(col);
        Thread t21 = new Thread(b2);
        t21.start();
    }
}

Class B implements Runnable {

    private final Set<T> someSet;

    private B(Set<T> someSet) {
      this.someSet = someSet;
    }

    public void method(final T obj) {
        someSet.add(obj);
    }

    public void run() {
        method()
    }
}
于 2013-03-06T18:28:32.267 に答える