Alternative to Java Synchronized?
I have made a simple HTTP server that starts a new thread each time a new client connects.
Each client can add, get or remove a text string from an ArrayList on the server.
The concurrency in the program could be solved by synchronizing the ArrayList like:
List items = Collections.synchronizedList(new ArrayList());
But I have heard that Java Synchronized is not very efficient and even has some security holes. What are the alternative to using Java Synchronized, if I would like to make an efficient concurrent system?
[585 byte] By [
lokpesta] at [2007-10-3 4:22:48]

> But I have heard that Java Synchronized is not very
> efficient and even has some security holes.
Security holes? What security holes and who said that synchronized has them?
> What are the alternative to using Java Synchronized, if I
> would like to make an efficient concurrent system?
Well, the whole point of synchronization in Java is to properly enable multi-threaded access to common resources when the Threads (for performance reasons) are legitimately allowed to cache stuff locally, invisibly to other threads.
The new JDK5 concurrency library (java.util.concurrent and sub-packages) allows for some more sophisticated concurrency constructs. For example, there is the concept of a ReadWriteLock - to minimize synchronization overheads in the case of reading/writing data.
readWriteLock_.readLock().lock();
try {
//Do something which accesses but does not update data
}
finally {
readWriteLock_.readLock().unlock();
}
> I have made a simple HTTP server that starts a new
> thread each time a new client connects.
>
> Each client can add, get or remove a text string from
> an ArrayList on the server.
Is the ArrayList shared by all threads on the server? Can all threads write to it?
> The concurrency in the program could be solved by
> synchronizing the ArrayList like:
There are other things you can try now. Look at the java.utils.concurrent packages if you're using JDK 1.5
> But I have heard that Java Synchronized is not very efficient
Monitors are expensive and synchronization does force clients to wait. No getting around that.
> and even has some security holes.
Please list those security holes. I'm ignorant of them.
> What are
> the alternative to using Java Synchronized, if I
> would like to make an efficient concurrent system?
Write thread-safe code. Don't have writable, shared data.
%
Well what I would like to know is how to write multithreaded programs that accesses (read/write) shared memory without using synchronized.
I was told that if you cannot avoid having shared memory and multiple threads manipulating this memory, the "right" way to make an efficient concurrent system is to avoid using Synchronized and do it on you own using semaphores (and not those introduced in java 5).
Does this make any sense or is it just some old-drunken-man-talk and a tradition belonging to the dark ages? Does the industry implement concurrent systems without the use of Synchronized?
Make a time test to see how fast synchronized is. I would say that it is fast enough for most needs, unless you specifically notice that it is the bottleneck. There is no faster way for multithread safe code in any language than synchronized - monitors are not for free.
Starting a Thread is way much more expensive.
Try this to see how much a list update is hampered by at a minimum by synchronized. This difference will of course be much less the moment you start to do removes and look-ups in the list or any logic with the data.
public static void main(String[] args) {
int ADDS=1000000;
long sTime, eTime;
//without synchronized list
List items = new ArrayList();
sTime=System.currentTimeMillis();
for (int i = 0; i < ADDS; i++) {
items.add("");
}
eTime=System.currentTimeMillis();
long simpleAddTime=eTime-sTime;
//without synchronized list
List syncitems = Collections.synchronizedList(new ArrayList());
sTime=System.currentTimeMillis();
for (int i = 0; i < ADDS; i++) {
syncitems.add("");
}
eTime=System.currentTimeMillis();
long synchronizedAddTime=eTime-sTime;
System.out.println(ADDS+" non synchronized list adds took "+simpleAddTime+" ms");
System.out.println(ADDS+" synchronized list adds took "+synchronizedAddTime+" ms");
}
Test program results in:
1000000 non synchronized list adds took 281 ms
1000000 synchronized list adds took 407 ms
Seems like synchronized isn't that expensive
Gil
> I was told that if you cannot avoid having shared
> memory and multiple threads manipulating this memory,
> the "right" way to make an efficient concurrent
> system is to avoid using Synchronized and do it on
> you own using semaphores (and not those introduced in
> java 5).
That's definitely garbage. Who told you this!?
Come on Dave, this is the new development paradigm: PBR. (Programming By Rumour.)
> the "right" way to make an efficient concurrent> system is to avoid using Synchronized and do it on> you own using semaphoresI think you mean semafives. No serious programmer has used a semafour since JDK5 came out; that's so last year.
Ok so it seems that I can just ignore these urban legends.
If I only have the following operations: PUT, DELETE, GET that multiple threads can execute concurrently on the same instance of an ArrayList then it should be enough to just:
List queue = Collections.synchronizedList(new ArrayList());
and I can be sure that no elements will be deleted while some other thread is reading it?
> and I can be sure that no elements will be deleted
> while some other thread is reading it?
Not necessarily as you could be reading via an iterator; for example
for (Object item : queue) {
//if someone adds/removes from queue I may find a ConcurrentModificationException is thrown
}
See the Javadoc against the Collections.synchronizedList method for what you need to do in that case.
but as long as I only just use the List methods add, get, remove...it should work correctly right?
> > the "right" way to make an efficient concurrent
> > system is to avoid using Synchronized and do it on
> > you own using semaphores
>
> I think you mean semafives. No serious
> programmer has used a semafour since JDK5 came out;
> that's so last year.
ROFL
You just made my day. Thanks.
> but as long as I only just use the List methods add,
> get, remove...it should work correctly right?
Well, as long as you don't use the iterator method, all of the others are safe for multi-threaded access in the sense that:
1. reads and writes are not happening simultaneously across multiple threads
2. writes in one thread are visible to other threads
The synchronized monitor operation is kind of fundamental - any more fancy synchronization functions, Semaphores etc. are going to depend on it for their thread-safety. So even if you use them you will be using synchronized.
You might want to do your own synchronization, rather than use the synchronizedList wrapper. That way you can be more selective but, to be honest, in the context of a client - server environment the costs associated with the actual TCP/IP activities is going to completely bury any slight overheads from sychronization, providing you don't do anything daft.
> The synchronized monitor operation is kind of
> fundamental - any more fancy synchronization
> functions, Semaphores etc. are going to depend on it
> for their thread-safety. So even if you use them you
> will be using synchronized.
I think you'll find that's not true actually. But regardless the chances that the concurrency libraries are more poorly implemented than a roll-your-own solution is effectively zero.
> I think you'll find that's not true actually.Are you sure? Then how do they get around the memory sync problems and instruction reordering?
> Are you sure? Then how do they get around the memory
> sync problems and instruction reordering?
Looking at the AbstractQueuedSynchronizer class, they use the volatile keyword and the sun.misc.Unsafe class, whose methods are all native, non-synchronized
> > Are you sure? Then how do they get around the
> memory
> > sync problems and instruction reordering?
>
> Looking at the AbstractQueuedSynchronizer
> class, they use the volatile keyword and the
> sun.misc.Unsafe class, whose methods are all
> native, non-synchronized
You can invoke the synchronized mechanism from C in JNI methods.