开发者

Java: Returning copy of object

In the following code snippet, why is it desirable to return a copy of data[i]. What exactly happen in a multi-threa开发者_开发知识库ded environment if copy is not made.

protected Object[] data; 
..
public synchronized Object get(int i) 
throws NoSuchElementException 
{   if (i < 0 || i >= size ) 
      throw new NoSuchElementException();
    return data[i]; 
}


why is it desirable to return a copy of data[i].

You're returning a copy of the reference at index i, not a copy of the object.

Unless you create a copy of the object through for instance data[i].clone(), you'll always have a single object and share references to it among your threads. There is nothing wrong with sharing references to a single object among several threads.

What exactly happen in a multi-threaded environment if copy is not made.

Well, unless you synchronize your threads using the synchronized methods, wait/notify or the java.util.concurrent-classes you may end up with race-conditions. A race condition is basically a situation where the result of the execution is dependent on the particular scheduling (the order in which the threads may execute).

If you share objects of a certain class among threads, you should design it to be "thread safe". If your object represents a value object I recommend you to make it immutable.


Well, I see nothing wrong with the method as it is - it is not making a copy. It depends on what are you planning to do with the returned object after. If you will be modifying it from different threads, then it is a good idea to return a copy for each thread.


Since the method is synchronized and unless nobody else in the same package manipulates the data array there should be no multi-threaded issues.


Because it could be more comfortable for the calling code. If you don't return a copy (as shows your example) you have to synchronize on the returning reference (data[i]) if you want to avoid race conditions.


desirable to return a copy of data[i]

Since your get() is synchronized it is likely that several threads will access the objects in parallel. Now this will lead to problems if the following points are true

  • the objects stored in the array are muteable (can change state)
  • the objects methods are not synchronized (the object is not threadsafe)

If these are true you could end up with objects in an invalid state if two threads manipulate the objects at the same time. Creating a copy of the objects prevents this, since every thread will handle its own copy.


With multiple threads having direct access to the same object, you can get issues with unexpected behavior.

Consider the following:

Thread A:

Object foo = get(1);
foo.member += 5;

Thread B:

Object bar = get(1);
bar.member = 2;

Assuming these 2 threads are running simultaneously, you have no way of knowing what the end state of the object stored in data[1] will be. The point at which threads switch control isn't predictable, and while you might be fine 99% of the time, your code can be open to intermittent bugs.

What you would really want to do is protect any methods that modify the state of the objects data[] with the "synchronized" key word. Getters, setters, etc should all be synchronized. Having a synchronized method which just hands out references to objects is pointless.


Please do not use clone to create copy , it has its own faults. use copy constructor or create a new object and set the member values and return the same.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜