Reputation: 11944
Hi I have a class with multiple methods in which I require synchronized blocks in all of the methods like this:
public class Test2 {
private Object mutex=new Object();
private OtherClass obj=new OtherClass();
public void method1(){
//do some stuff
synchronized (mutex) {
obj.//some method
//do some stuff
}
//do other stuff
}
public void method2(){
//do some stuff
synchronized (mutex) {
obj.//some method
//do some stuff
}
//do other stuff
}
public void method3(){
//do some stuff
synchronized (mutex) {
obj.//some method
//do some stuff
}
//do other stuff
}
public void method4(){
//do some stuff
synchronized (mutex) {
obj.//some method
//do some stuff
}
//do other stuff
}
}
I am using mutex to synchronize the blocks, so what happens if method1
is being used, the other method2
synchronized block waits until the flow comes out of the synchronized block of method1
.
I dont want this to happen, so what should i do? I know that as I am using mutex for all the methods, so it locks the method2
synchronized block. I want to know what should I do to remove this? Should I create member variables for each method to use, or is there another way around this?
I want the other thread to wait only if the same method is called.. like if two threads class mehod1 so the second thread should wait. but if the second thread calls method2 it should not wait.
Upvotes: 0
Views: 127
Reputation: 6358
You have to use different monitor objects (mutex
in your code) for each method call if you want to achieve this and synchornize to them. If you have many methods, you could use some kind of collection to hold your mutex objects:
public class Test2 {
private Object[] mutexes=new Object[2];
private OtherClass obj=new OtherClass();
private synchronized Object getMutex(int i) {
if(mutexes[i] == null) {
mutexes[i] = new Object();
}
return mutexes[i];
}
public void method1(){
//do some stuff
synchronized (getMutex(1)) {
//do some stuff
}
//do other stuff
}
public void method2(){
//do some stuff
synchronized (getMutex(2)) {
//do some stuff
}
//do other stuff
}
}
Note that if you synchronize on a per method basis but each method accesses the same object (obj
in your case) from the synchronized
blocks, the access to that specific object is still not thread-safe.
The other option would be to initialize all mutexes in the constructor instead of creating them on-demand in the getMutex()
method:
public Test() {
for(int i = 0; i < mutexes.length()) {
mutexes[i] = new Object();
}
}
Upvotes: 2
Reputation: 9522
Just use different monitors for every method.
public class Test2 {
private Object mutex1 = new Object(), mutex2 = new Object();
private OtherClass obj=new OtherClass();
public void method1() {
//do some stuff
synchronized (mutex1) {
obj.//some method
//do some stuff
}
//do other stuff
}
public void method2() {
//do some stuff
synchronized (mutex2) {
obj.//some method
//do some stuff
}
//do other stuff
}
}
If you have a lot of methods, you can also pack them in an array.
Upvotes: 2
Reputation: 62469
Judging by your comment I assume you want per-method synchronization instead of per-object. In this case the simplest way would be to declare a separate monitor object for each method i.e. mutex1
, mutex2
, etc.
Upvotes: 4