What does it mean when somebody says "Result is not Thread-Safe" - java

I was writing an app specific wrapper over Java HBase APIs when I read this doc:
http://hbase.apache.org/apidocs/org/apache/hadoop/hbase/client/Result.html
It says This class is **NOT THREAD SAFE**.
What exactly does it mean by not thread safe. I'm basically a C++ programmer and if someone says the function strtok() is not thread safe, I'll not use it in a multithreaded env. Its something like strtok() uses a static variable and calls to this function by two different threads is not a good idea.
Is it the same when it comes to JAVA?
I have a function:
public String get(String key, String family) {
Get get = new Get(key.getBytes());
get.addFamily(family.getBytes());
Result result = null;
try {
result = _table.get(get);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return "";
}
The function get might be called by multiple threads. Does it make Result unsafe to use somehow?

What exactly does it mean by not thread safe.
It means that if the given class object is accessed via various Threads then calling its method(s) within those Threads may result in unpredictable results because of unwanted interaction between the various Threads. The basic reason for this unpredictable result is the sharing of same data of an object among various threads. You can look at here at Wikipedia Article to know more about Thread-safety.
After going through your code I am seeing that you are using a member variable _table in line result = _table.get(get); . So , most probably it is not Thread-safe.

If a class is "not Thread-Safe", its methods cannot be called (on the same instance) by multiple threads without additional synchronization. For example, you can't simultaneously iterate over an ArrayList in one thread, and modify its contents in other.
In your case it shouldn't be a problem, because in each invocation of function get new instance of Result is created, so these threads operate on different Result objects.

When you read that Result is not thread safe it means that if you have a situation where multiple threads can access this result object you need to make sure the usage is synchronized (see here for list of ways to synchronize access).
If your code will stay as is, i.e. each call to get will generate its own new instance of Result you are ok. If you'd keep this Result instance between calls in the object and it will be used in multiple calls you'd need to protect the access to that Result object

Related

Instance variable and thread safety in java

Below is an example class (modified from the one I was testing), I would like to know if this is a thread safe class.
I see other posts and blogs where its been answered that instance variables are not necessarily thread safe. (most of the examples shown with primitive types)
When I create the OutputResponse object outside the method and load test it from soapui it was failing, but when I create the object inside the method the load test was always succeeding.
#Service
public class ExampleProvider {
private OutputResponse outputResponse;
#Post
#Path("/test")
#Consumes("application/json")
#Produces("application/json")
public OutputResponseEntity execute (InputRequest inputRequest) {
outputResponse = new OutputResponse();
outputResponse.setSomeValue("this is test");
populateOutputResponse();
}
private OutoutResponseEntity<OutputResponse> populateOutputResponse () {
if(null != inputRequest) {
outputResponse.setSomeOtherValue(inputRequest.getName());
}
return new OutputResponseEntity(outputResponse,httpstatus.OK);
}
}
Your posted code doesn't seem to be quite right, syntactically -- did you mean something like:
public OutputResponseEntity execute (InputRequest inputRequest) {
outputResponse = new OutputResponse();
outputResponse.setSomeValue("this is test");
return populateOutputResponse(inputRequest);
}
Assuming that's what you meant, then it seems like multiple threads are using the same instance of ExampleProvider. That would explain why making outputResponse local to execute (and then you would probably want to pass it to populateOutputResponse too) fixes your tests.
If multiple threads are using the same instance of ExampleProvider then, as your code is now, outputResponse is also being shared among those threads, and no synchronization is being done to prevent race conditions. So, something like this could happen:
thread 1 completes setSomeOtherValue(...) on the shared instance of outputResponse
JVM context switches to thread 2 and completes setSomeValue(...) on the same instance of outputResponse. outputResponse now contains state from both threads 1 and 2
JVM context switches back to thread 1, which then creates an OutputResponseEntity based on this mixed-state object.
If you make outputResponse local to the execute method and just pass it around, it effectively becomes thread-local memory, so you'll have a separate instance of that object per thread. This is probably what you want; if you don't need to share information between threads, just make it a local var. If you really do need to coordinate sets/gets between threads (which doesn't seem to be the case in this simple example), then you'll need to do some sort of synchronization and/or design the program flow better (depending on your needs).
This class is not thread-safe by design. But it's clearly used as a component in some framework. Not it is possible, that this framework ensures that no instance of your ExampleProvider is shared between threads. If that's the case, than thread-safety of your class is not a concern and will not influence your tests outcome.

Synchronized block and variable scope

Can anyone explain to me how the parameter map will be affected in the following code if two threads access it at the same time. Is the map exposed to thread safety issues because it is not inside the synchronized block?
public void fun(String type, String name, Map<String, Object> parameters) {
parameters.put(Constants.PARM_TYPE, type);
parameters.put(Constants.PARM_NAME, name);
try {
synchronized (launcher) {
launcher.launch(type, bool, parameters);
}
} catch (Exception e) {
logger.error("AHHHHH, the world has ended!",e);
}
}
I have looked at the following but I'm still questioning it: Synchronized and the scope of visibility
If your parameters instances are separate (as you mentioned in your last comment), then there is no problem with this code.
The method parameters - besides Map parameters - are just 2 Strings, so there are no synchronisation issues regarding them.
To put the synchronized block onto method level or on launcher: They're different objects. If you put on method, it will synchronize on this, otherwise on launcher. Since you want to protect the 'launcher', you have to "build the fence" as close as you can - so synchronizing on launcher is OK.
There is another technique which is using a Object lockObject = new Object(), and does the synchronization on that object, but for this purpuse I think it's overkill, but you can do that.
Imagine if you had a shared Map.
private Map<String, Object> map = new HashMap<String,Object>();
that is being updated by many threads as displayed in your example.
new Thread(new Runnable(){
public void run(){
fun("a","b", map);
}
}).start();
new Thread(new Runnable(){
public void run(){
fun("a","b", map);
}
}).start();
Each thread may update the map at the same time which could lead to A Beautiful Race Condition
If multiple threads have a handle to the same parameters instance and they call this method (which modifies the map) with a non-thread-safe map implementation, all kinds of bad things can/will happen (e.g. map corruption which may/may not manifest itself as exceptions like NullPointerException).
Assuming multiple threads are accessing the method fun(), the way map works is if you insert the same key multiple times then the value of that key would be overridden each time. But this might not be the only problem. There could be race conditions and corruption issues too. If you want an implicitly thread safe data structure, I assume a HashTable will get your job done.
if more than one thread executes that code concurrently passing the same object as the parameter map then you will have a race condition.
This will definitely cause thread safety issues unless you:
use the right Map implementation, based on your requirements and the Map implementation concurrent behavior (ConcurrentHashMap for instance, but this depends a lot on the actual requirements for your app)
or write thread safe code yourself (probably using synchronization primitives like 'synchronized').
IMPORTANT: Please notice that just moving the lines of code that modify the map into the synchronized block won't necessarily remove the race condition as you'll have to consider which other threads in your app may try to modify the map and which object they will use to synchronize their access to it. The code in the function is using a reference to 'launcher' to synchronize. Any other thread modifying the map without synchronization or with synchronization over an object different than 'launcher' will cause a race condition

synchronization ideas for a method

I have a multithreaded class A which accesses the following insert() method of another class B (A has only a single instance of B).
Instead of making the entire method synchronized, are there any better ways to synchronize the following method? (to reduce the synchronization overhead)
private void insert(byte[] shardKey, byte[] queueKey,
byte[] value, PipelineMessageType msgType) {
PipelineMessage pipelineMessage = new PipelineMessage(queueKey,
value, msgType);
LinkedBlockingQueue<PipelineMessage> queue;
JedisShardInfo shardInfo = shardedJedis.getShardInfo(shardKey); // shardedJedis is an instance variable of this class
String mapKey = shardInfo.getHost() + shardInfo.getPort();
queue = shardQueue.get(mapKey); // shardQueue is an instance variable of this class
boolean insertSuccessful = queue.offer(pipelineMessage);
if(!insertSuccessful) {
// perform the pipeline sync - flush the queue
// use another thread for this
// (processing of queue entries is given to another thread here)
// queue would be empty now. Insert (k,v)
queue.offer(pipelineMessage);
}
}
I tried to synchronize only the fragment which accesses the instance variables but there might be a scenario where 2 threads try to insert into a full queue and enter the if block. Then 2 threads might process the queue entries which I don't want to happen.
Any suggestions are appreciated. Thank you in advance.
Seems to me that if JedisShardInfo would be a read-only item, then you should need to protect/synchronize it. So you could synchronize only from the line
queue= ...
Otherwise, almost everything should be synchronized, except the first statement (declaration of pipeline message), and then I really wonder if it changes much compared to declaring the whole method synchronized.
Also, if you got other points of synchronization, I mean other methods or block codes that are synchronized on this, you should consider splitting them and synchronize on different data members of this depending on which data members you wish to protect from multi-threading :
Object lockerA = new Object() {};
synchronized( lockerA )
{}//sync
Well, not much to say. :)
Regards,
Stéphane
The key to correct synchronization is to follow this pattern:
synchronize(lockObjectForState) { // All code that alters state must also synchronise on the same lock
while(!stateOkToProceed()) {
try {
lockForState.wait();
} catch (InterruptedException e) {
// handle if your thread was interrupted deliberately as a single to exit, or spuriously (in which case do nothing)
}
}
updateState();
lockForState.notifyAll();
}
java.util.concurrent package offer many thread-safe implementations of classes needed to solve common threading problems. Consider using a BlockingQueue.

Piping data between threads with Java

I am writing a multi-threaded application that mimics a movie theater. Each person involved is its own thread and concurrency must be done completely by semaphores. The only issue I am having is how to basically link threads so that they can communicate (via a pipe for instance).
For instance:
Customer[1] which is a thread, acquires a semaphore that lets it walk up to the Box Office. Now Customer[1] must tell the Box Office Agent that they want to see movie "X". Then BoxOfficeAgent[1] also a thread, must check to make sure the movie isn't full and either sell a ticket or tell Customer[1] to pick another movie.
How do I pass that data back and forth while still maintaining concurrency with the semaphores?
Also, the only class I can use from java.util.concurrent is the Semaphore class.
One easy way to pass data back and forth between threads is to use the implementations of the interface BlockingQueue<E>, located in the package java.util.concurrent.
This interfaces has methods to add elements to the collection with different behaviors:
add(E): adds if possible, otherwise throws exception
boolean offer(E): returns true if the element has been added, false otherwise
boolean offer(E, long, TimeUnit): tries to add the element, waiting the specified amount of time
put(E): blocks the calling thread until the element has been added
It also defines methods for element retrieval with similar behaviors:
take(): blocks until there's an element available
poll(long, TimeUnit): retrieves an element or returns null
The implementations I use most frequently are: ArrayBlockingQueue, LinkedBlockingQueue and SynchronousQueue.
The first one, ArrayBlockingQueue, has a fixed size, defined by a parameter passed to its constructor.
The second, LinkedBlockingQueue, has illimited size. It will always accept any elements, that is, offer will return true immediately, add will never throw an exception.
The third, and to me the most interesting one, SynchronousQueue, is exactly a pipe. You can think of it as a queue with size 0. It will never keep an element: this queue will only accept elements if there's some other thread trying to retrieve elements from it. Conversely, a retrieval operation will only return an element if there's another thread trying to push it.
To fulfill the homework requirement of synchronization done exclusively with semaphores, you could get inspired by the description I gave you about the SynchronousQueue, and write something quite similar:
class Pipe<E> {
private E e;
private final Semaphore read = new Semaphore(0);
private final Semaphore write = new Semaphore(1);
public final void put(final E e) {
write.acquire();
this.e = e;
read.release();
}
public final E take() {
read.acquire();
E e = this.e;
write.release();
return e;
}
}
Notice that this class presents similar behavior to what I described about the SynchronousQueue.
Once the methods put(E) gets called it acquires the write semaphore, which will be left empty, so that another call to the same method would block at its first line. This method then stores a reference to the object being passed, and releases the read semaphore. This release will make it possible for any thread calling the take() method to proceed.
The first step of the take() method is then, naturally, to acquire the read semaphore, in order to disallow any other thread to retrieve the element concurrently. After the element has been retrieved and kept in a local variable (exercise: what would happen if that line, E e = this.e, were removed?), the method releases the write semaphore, so that the method put(E) may be called again by any thread, and returns what has been saved in the local variable.
As an important remark, observe that the reference to the object being passed is kept in a private field, and the methods take() and put(E) are both final. This is of utmost importance, and often missed. If these methods were not final (or worse, the field not private), an inheriting class would be able to alter the behavior of take() and put(E) breaking the contract.
Finally, you could avoid the need to declare a local variable in the take() method by using try {} finally {} as follows:
class Pipe<E> {
// ...
public final E take() {
try {
read.acquire();
return e;
} finally {
write.release();
}
}
}
Here, the point of this example if just to show an use of try/finally that goes unnoticed among inexperienced developers. Obviously, in this case, there's no real gain.
Oh damn, I've mostly finished your homework for you. In retribution -- and for you to test your knowledge about Semaphores --, why don't you implement some of the other methods defined by the BlockingQueue contract? For example, you could implement an offer(E) method and a take(E, long, TimeUnit)!
Good luck.
Think it in terms of shared memory with read/write lock.
Create a buffer to put the message.
The access to the buffer should be controlled by using a lock/semaphore.
Use this buffer for inter thread communication purpose.
Regards
PKV

correct synchronization of a map object created in the main thread and passed onto new threads

I'm trying to develop a program that takes requests for data which is stored in a map. The map is declared in the main method as shown below:
Map m = Collections.synchronizedMap(new HashMap());
synchronized(m) {
while (listening) {
new BrokerLookupServerHandlerThread(serverSocket.accept(), m).start();
}
}
The code for the BrokerLookupServerHandlerThread takes the input and makes it one of the object's variables. If I use it in this class, will the original map be updated as well? I understand that Java is pass by value, (I'm used to C/C++) so I just wanted to be sure if this implementation of a synchronized object makes sense.
private Socket socket = null;
//private String t ="MSFT";
public Map m;
public BrokerLookupServerHandlerThread(Socket socket, Map m) {
super("NamingServerHandlerThread");
this.socket = socket;
this.m = m;
System.out.println("Created new Thread to handle client");
}
Thanks for your help.
Yes original object will be updated. I suggest you use ConcurrentHashMap though.
A hash table supporting full
concurrency of retrievals and
adjustable expected concurrency for
updates. This class obeys the same
functional specification as Hashtable,
and includes versions of methods
corresponding to each method of
Hashtable. However, even though all
operations are thread-safe,
retrieval operations do not entail locking, and there is not any
support for locking the entire table
in a way that prevents all access.
This class is fully interoperable with
Hashtable in programs that rely on its
thread safety but not on its
synchronization details.
Yes, changes made to the map will be seen by both threads.
Java does indeed use pass by value - but the value in this case is a reference (similar to a pointer). The value of a reference-type variable in Java is always a reference to an object, or null. It's never the object itself.
So your code won't create a new map. There are very few operations which implicitly create a new object. I can only think of the use of string literals (where the literals are interned anyway) and autoboxing of primitive types. Other than that, you'll only get a new object via the new operator. (Obviously any method you call could create a new object too...)
Note that this is entirely separate to the issue of synchronization between threads. The business about copying objects vs copying references is orthogonal to threading. In this case it looks like you've solved the threading aspect using Collections.synchronizedMap; as Pangea says you may want to use ConcurrentHashMap instead which won't use nearly as much locking (if any). Another implementation of the ConcurrentMap interface is ConcurrentSkipListMap. Look at the docs for both classes to decide what suits you best.

Categories

Resources