Reputation: 381
I have a class Library
which is a third-part library that I don't have access to the source code. This class is used in different class of my project, such as
public class MyOwnClass1 {
private Library lib;
public void doTask () {
String res = lib.libMethod1();
... ... ...
}
}
However, it turns out that the class Library
is not thread-safe, for instance, when the method libMethod1
is called simultaneously in different threads, it causes weird problems.
Thus, I have to implement my own thread-safe mechanisms, the 1st one is to encapsulate the Library
variable into an other class.
public class SafeLibrary {
private Library lib;
private Object mutex = new Object();
... ... ...
public String doTask () {
synchronized(this.mutex) {
return this.lib.libMethod1();
}
}
... ... ...
}
But as I said, the Library
class is used in different methods of different class. If I have to place all the related method into the new SafeLibrary
class, it will cost a lot of code modification.
So Here is the 2nd idea:
public class SafeLibrary {
private Library lib;
private Object mutex = new Object();
public Object getMutex() {
return this.mutex;
}
public Library getLib() {
return this.lib;
}
}
Then I synchronize the method access in my own class:
public class MyOwnClass1 {
private SafeLibrary lib;
public void doTask () {
synchronized(lib.getMutext()) {
String res = lib.getLib().libMethod1();
... ... ...
}
}
}
By using the 2nd solution, I only have to do some small modifications in related methods. But the getMutex()
seems an improper way to go.
I'd like to know which solution is correct, or if there is a an other better solution ? Thanks.
Upvotes: 0
Views: 92
Reputation: 11017
If Library and the methods you want to use are not final, and you create the library object yourself (rather than getting it from a static method of Library itself), then you can create your own class:
public class SynchronizedLibrary extends Library {
public synchronized String libMethod1() {
super.libMethod1();
}
}
Then all you have to do is replace the constructor calls, and can even leave the declared type as plain old Library (although you may not want to).
Upvotes: 1
Reputation: 11267
You have two options, you can either synchronize your class or synchronize a particular methods. What you did with was synchronize a class. Here's an example on synchronizing a class: https://docs.oracle.com/javase/tutorial/essential/concurrency/syncrgb.html
Here's an example of synchronizing a method: https://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html
Basically just add the word "synchronized" after the "public" and before the return value. Think of it like adding "final" to a method.
The best solution will depend on your software architecture. If it's just that one method you are worried about and that method is a characteristic of the object you are creating, then just synchronize the method. If you're creating an independent object that other objects/threads need, then synchronize the object.
Upvotes: 1