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

在 B 类中有一个名为“method”的方法,其中编辑了 Set Collection。该编辑是基于 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())
    }
}

但是当从不同的“A”实例访问时,该 Set不需要并发控制。只有在一个 A 实例中,它才需要为所有 B 实例锁定

我的意思是,当 A 的 2 个实例正在运行时,不应让它们等待。但是在一个 A 实例中,如果 2 个 B 对象选择相同的 obj,它们必须在 LOCK.wait 中等待。

我不认为 LOCK 可以成为非静态的,因为 A 调用了 B 的多个实例。我们可以在这里调整 LOCK 对象以获得更好的跨 A 对象的并发性。

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 回答