Reputation: 4198
There are multiple instance of Class A that runs at a time.
Class A calls multiple instances of Class B in its run.
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();
}
}
There is method named "method" in class B where a Set Collection is edited. That edit is done based on static lock in Class 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())
}
}
But that Set does not need concurrency control when it is accessed from different "A" instances. Only within an A instance, it needs to be locked for all B instances.
By this I mean, that when 2 instances of A are running, they should not be made to wait. But within an A instance if 2 B objects pick same obj, they have to wait inside LOCK.wait.
I don't think that LOCK can be made non-static as A calls multiple instances of B.Can we tune LOCK object here for better concurrency across A objects.
Upvotes: 0
Views: 136
Reputation: 53694
You can create a thread-safe instance of the shared collection and pass it to all the Bs for a given A.
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()
}
}
Upvotes: 1