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]
# 1

> 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();

}

oxbow_lakesa at 2007-7-14 22:25:08 > top of Java-index,Java Essentials,Java Programming...
# 2

> 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.

%

duffymoa at 2007-7-14 22:25:08 > top of Java-index,Java Essentials,Java Programming...
# 3

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?

lokpesta at 2007-7-14 22:25:08 > top of Java-index,Java Essentials,Java Programming...
# 4

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

gilroittoa at 2007-7-14 22:25:08 > top of Java-index,Java Essentials,Java Programming...
# 5

> 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!?

dcmintera at 2007-7-14 22:25:08 > top of Java-index,Java Essentials,Java Programming...
# 6
Come on Dave, this is the new development paradigm: PBR. (Programming By Rumour.)
DrClapa at 2007-7-14 22:25:08 > top of Java-index,Java Essentials,Java Programming...
# 7
> 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.
oxbow_lakesa at 2007-7-14 22:25:08 > top of Java-index,Java Essentials,Java Programming...
# 8

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?

lokpesta at 2007-7-14 22:25:08 > top of Java-index,Java Essentials,Java Programming...
# 9

> 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.

oxbow_lakesa at 2007-7-14 22:25:08 > top of Java-index,Java Essentials,Java Programming...
# 10
but as long as I only just use the List methods add, get, remove...it should work correctly right?
lokpesta at 2007-7-14 22:25:08 > top of Java-index,Java Essentials,Java Programming...
# 11

> > 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.

CeciNEstPasUnProgrammeura at 2007-7-14 22:25:08 > top of Java-index,Java Essentials,Java Programming...
# 12

> 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

oxbow_lakesa at 2007-7-14 22:25:08 > top of Java-index,Java Essentials,Java Programming...
# 13

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.

malcolmmca at 2007-7-14 22:25:08 > top of Java-index,Java Essentials,Java Programming...
# 14

> 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.

dcmintera at 2007-7-14 22:25:08 > top of Java-index,Java Essentials,Java Programming...
# 15
> 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?
-Kayaman-a at 2007-7-21 10:29:31 > top of Java-index,Java Essentials,Java Programming...
# 16

> 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

oxbow_lakesa at 2007-7-21 10:29:31 > top of Java-index,Java Essentials,Java Programming...
# 17

> > 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.

malcolmmca at 2007-7-21 10:29:31 > top of Java-index,Java Essentials,Java Programming...