锁定静态对象

时间:2013-03-06 18:00:38

标签: java multithreading

一次运行多个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”实例访问时, 需要并发控制。仅在A实例中,需要为所有B实例锁定

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

我不认为LOCK可以是非静态的,因为A调用B的多个实例。我们可以在这里调整LOCK对象,以便在A对象之间实现更好的并发性。

1 个答案:

答案 0 :(得分: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()
    }
}