• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Tim Cooke
  • Campbell Ritchie
  • paul wheaton
  • Ron McLeod
  • Devaka Cooray
Sheriffs:
  • Jeanne Boyarsky
  • Liutauras Vilda
  • Paul Clapham
Saloon Keepers:
  • Tim Holloway
  • Carey Brown
  • Piet Souris
Bartenders:

synchronization in vector

 
Ranch Hand
Posts: 43
Netbeans IDE Firefox Browser Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Was going thru the java.util.Vector source code.
Found the following snippets:


/**
* The number of valid components in this <tt>Vector</tt> object.
* Components <tt>elementData[0]</tt> through
* <tt>elementData[elementCount-1]</tt> are the actual items.
*
* @serial
*/
protected int elementCount;

....
.....
/**
* Returns the number of components in this vector.
*
* @return the number of components in this vector.
*/
public synchronized int size() {
return elementCount;
}

Read,assignment operations on all primitive dataTypes except long and double are atomic.

In size(),elementCount cannot be corrupted since all read/assignment operations on it are completed with-in one CPU cycle.
And size() shall return whatever value is held by elementCount.
Why is the method synchronized then?
 
Ranch Hand
Posts: 291
Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
If the variable is volatile, that means the thread will get the current value. Vector variables are not volatile, therefore, sync ensures the thread gets the current value.

This is not so easy to understand. See chapter 17 of the Java spec: Chap17
 
Ranch Hand
Posts: 1970
1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Unless there is a "synchronized" block, or field is declared "volatile", different threads are allowed to hold their own copies of a value. The synchronisation in Vector is preventing this.

In general, however, you should not look at Vector as an example of good programming. It is a very old class and should not be used in new code - use ArrayList instead. Vector's synchronisation is mostly pointless.
 
sarvesh meens
Ranch Hand
Posts: 43
Netbeans IDE Firefox Browser Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Suppose that 'elementCount' is made volatie.
size() can be made unsynchronized then?


Checked the source of ConcurrentHashMap.
Some of the variables are volatile but some are not.

/**
* The number of elements in this segment's region.
*
*/
transient volatile int count;

/**
* Number of updates that alter the size of the table. This is
* used during bulk-read methods to make sure they see a
* consistent snapshot: If modCounts change during a traversal
* of segments computing size or checking containsValue, then
* we might have an inconsistent view of state so (usually)
* must retry.
*/
transient int modCount;

/**
* The table is rehashed when its size exceeds this threshold.
* (The value of this field is always (int)(capacity *
* loadFactor).)
*/
transient int threshold;

modCount and threshold are always used with-in locked blocks.
count is used unlocked blocks as well.
Hence,modCount and threshold are non-volatile while count is volatile.

I arrive @ the following conclusion:
* Variables in multi-threaded environment used in unblocked context should be made volatile.
* Variables in multi-threaded environment used in blocked context need not be made volatile.

Correct me if I'm wrong.
 
Peter Chase
Ranch Hand
Posts: 1970
1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
There are no simple rules for multi-threaded programming. You have to think through each case.

If you are new to multi-threading, I would recommend forgetting about "volatile" entirely. You never need volatile; it is just a way of gaining more concise code and/or small performance gain. Get used to using "synchronized" correctly and effectively.

By the way, ConcurrentHashMap is right at the other end of the code sophistication scale to Vector. ConcurrentHashMap has been carefully optimised to the Nth degree by very smart people. Some of the reasons for particular synchronisations, or the lack of them, are probably very subtle. It might be difficult to extract learning points for ordinary, non-performance-critical, code from ConcurrentHashMap.
 
sarvesh meens
Ranch Hand
Posts: 43
Netbeans IDE Firefox Browser Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
synchronization works,accepted.
But in many a place we dont really have to synchronize.
Just volatality will do.

Let's consider a class that is used from multiple threads.

eg: class MyDataStore
{
int myValue = -1;

public void set(int newValue)
{
myValue = newValue;
}

public int get()
{
return myValue;
}
}

* Neither of the methods need to be synchronized since the operations are atomic.
* But threads maynot read the current value of 'myValue' due to caching.
* We can prevent it by making get() synchronized.
* But it can also be achieved by making myValue volatile. It is this subtility that I'm exploring. Synchronization can be the lost resort.

Got one more query on ConcurrentHashMap.
Found the following in ConcurrentHashMap.
static final class Segment<K,V> extends ReentrantLock implements Serializable {
......
.......
transient volatile int count;
transient int modCount;

.....
.....
}

* modCount is used within locked blocks inside Segment.
* But it is accessed in unlocked blocks outside of Segment.

eg: public boolean isEmpty() {
final Segment[] segments = this.segments;
........
..........
int[] mc = new int[segments.length];
int mcsum = 0;
for (int i = 0; i < segments.length; ++i) {
if (segments[i].count != 0)
return false;
else
mcsum += mc[i] = segments[i].modCount;
}
......
.........
}
* Wont this lead to caching problem(since modCount is not volatile)?
 
Consider Paul's rocket mass heater.
reply
    Bookmark Topic Watch Topic
  • New Topic