Reputation: 31
I have question regarding thread safety. The below code which is inside the synchronisation block has external method call (httpClient.execute()) on class variable reference of the current object. Is this external call causes thread safety issue? If yes how to resolve this?
public class KeyClient {
private final HttpClient httpClient;
public getKey() {
synchronized (this) {
if (Paths.get("fileName").toFile().exists()) {
if (file == null) {
file = new File("fileName");
}
} else {
HttpResponse response = httpClient.execute();
Map map = mapper.readValue(response.getResponseBody(), Map.class);
file = new File("fileName");
mapper.writeValue(file, map);
}
}
}
}
public class HttpClient {
public HttpResponse execute() {
//Some code
return new HttpResponse(200, "");
}
}
Upvotes: 1
Views: 114
Reputation: 10814
The synchronized (this)
statement ensures that no other thread will enter the subsequent block while one thread already entered it. From this point of view the code is thread safe.
However, nothing protects httpClient
from being used from another non synchronized method on the KeyClient
class that is called from another thread.
Finally, there is always a potential for introducing deadlocks when synchronizing code that is beyond ones one control: should httpClient.execute()
at some point call back into your code, which in turn through a chain of complicated dependencies tries to aquire the monitor on KeyClient
. As it stands this is not a problem here. However, these sort of problems tend to be introduced once the code evolves and it is worth thinking of them early on.
Upvotes: 0
Reputation: 2430
You have two possible shared resources that you have to pay attention to. Both of them can compromise thread safety.
HttpClient instance inside KeyClient: Even though it's marked as final
, the KeyClient should be responsible for creating HttpClient in the constructor. You should not share HttpClient instance with any other class. Also, it's a good rule of thumb to check thread safety for each method of each class you're sharing in their JavaDoc.
The file with "fileName"
should be also considered as a shared resource, so be aware that another thread might write to the same file at the same time which will mess up your data. Ensure that each thread writes to its own file at the same time. A good approach is to generate a unique file name prefix on-the-fly when file is written. For example, it can be thread-ID-process-ID-timestamp-fileName.txt
Upvotes: 0
Reputation: 2210
Only one thread can enter synchronized
section so your http client instance is never used concurrently. Also, synchronized
section makes any entering/leaving thread to sync its state with other thread so it does not matter if http client has mutable state because it will be properly synchronized.
So code is thread safe.
Upvotes: 0
Reputation: 2119
No it will not.
If you call synchronized block whatever within the block also get locked.The lock is enabled when you enter a synchronized block and is disabled when you exit that block.
However calls to execute method by other threads are not locked -- anyone can call them at the same time.
Upvotes: 3
Reputation: 4993
The HTTPClient
is final
, which means it is a constant variable and it can't be changed after it is initialised. This code therefore most likely does not have any thread safety issues (unless of course there are mutable variables inside of the HTTPClient class that are unsynchronised).
Upvotes: 0