Is ArrayList in application object are thread safe?

G

Guest

Hi,

I want to keep a list of my visitors in an ArrayList which I place in the
application object like this:

Application("Visitors") = new ArrayList(); // The list of visitors

Then, each visitors update their own information in that list for every page
they visit.

Also, I add and remove visitors from the list as they come and go.

Can this cause concurrency situation and corrupt data? Do I need to lock the
Application("Visitors") each time I access it to add or to remove? Wouldn't
that be too much in term of performance? what is the best way to do this?

Thanks for any tips!

Stephane
 
S

Scott Allen

Can this cause concurrency situation and corrupt data? Do I need to lock the
Application("Visitors") each time I access it to add or to remove? Wouldn't
that be too much in term of performance? what is the best way to do this?

Yes, Stephane. You'll need to take care when modifying the list
itself. If the modifications are not done in a thread safe manner you
can end up with a corrupt list and strange runtime exceptions.

One approach is to use the thread safe ArrayList wrapper returned by
the Synchronized method. This makes your work easy, but may not be
what you need.

The synchronized wrapper makes individual operations thread safe, but
you might have code like this:

if(list.Count > 0)
Visitor v = list[0] as Visitor;

The problem with the above is that another thread might remove the
last visitor from the list between the time you check the Count
property and the time you retrieve the object with the [] indexer.
You'll get an exception.

The safest approach is to lock the list anytime you read or write:

lock(list.SyncRoot) {
// use the code above
}

.... and of course the safest approach is not going to be the most
performant approach.

Starting out, I would favor safety over performance, and run tests. In
most applications these locks won't kill performance. You can use
finer grained locks, or reader versus writer locks for more
throughput, but these add complexity.

If you do run into trouble I'd seriously consider storing the
information in a database. Relational databases excel at concurrency
management and fine grained locking.

Hope this helps,
 
G

Guest

Hi,

Thanks for your answer, it was helpful!

You think that managing visitors in a DB would be a more convenient way? I
thought it would be faster and simplier using application object.

Thanks,

Stephane


Scott Allen said:
Can this cause concurrency situation and corrupt data? Do I need to lock the
Application("Visitors") each time I access it to add or to remove? Wouldn't
that be too much in term of performance? what is the best way to do this?

Yes, Stephane. You'll need to take care when modifying the list
itself. If the modifications are not done in a thread safe manner you
can end up with a corrupt list and strange runtime exceptions.

One approach is to use the thread safe ArrayList wrapper returned by
the Synchronized method. This makes your work easy, but may not be
what you need.

The synchronized wrapper makes individual operations thread safe, but
you might have code like this:

if(list.Count > 0)
Visitor v = list[0] as Visitor;

The problem with the above is that another thread might remove the
last visitor from the list between the time you check the Count
property and the time you retrieve the object with the [] indexer.
You'll get an exception.

The safest approach is to lock the list anytime you read or write:

lock(list.SyncRoot) {
// use the code above
}

.... and of course the safest approach is not going to be the most
performant approach.

Starting out, I would favor safety over performance, and run tests. In
most applications these locks won't kill performance. You can use
finer grained locks, or reader versus writer locks for more
throughput, but these add complexity.

If you do run into trouble I'd seriously consider storing the
information in a database. Relational databases excel at concurrency
management and fine grained locking.

Hope this helps,
 
S

Scott Allen

Hi,

Thanks for your answer, it was helpful!

You think that managing visitors in a DB would be a more convenient way? I
thought it would be faster and simplier using application object.

It might still be simpler to keep an object around in the Application
object, but remember if your web application resets you'll loose all
the information, that is another advantage to using a database.
 
W

WJ

Stephane said:
You think that managing visitors in a DB would be a more convenient way ?

For stability, DB such as MS/SQL Server is recommended
I thought it would be faster and simplier using application object.

Yes, RAM is always the fastest regardless of what you do. Simply, because no
IO involved.

John
 
J

John Murray

A hybrid approach might also be an option. Use the database as the
underlying store, and spin it up on application start, but from there,
do all your user actions could be in memory ... this reduces your load
on the database (making it more performant for other needs.)

Another fairly simple approach that might provide benefits is to create
your own class that wraps an ArrayList and internally use a
ReaderWriterLock object to provide finer grain locking around the
methods of ArrayList that you need. This could also have the benefit if
encapsulating the logic for writing updates to the database and spinning
itself up.


Hi,

Thanks for your answer, it was helpful!

You think that managing visitors in a DB would be a more convenient way? I
thought it would be faster and simplier using application object.

Thanks,

Stephane


:

Can this cause concurrency situation and corrupt data? Do I need to lock the
Application("Visitors") each time I access it to add or to remove? Wouldn't
that be too much in term of performance? what is the best way to do this?

Yes, Stephane. You'll need to take care when modifying the list
itself. If the modifications are not done in a thread safe manner you
can end up with a corrupt list and strange runtime exceptions.

One approach is to use the thread safe ArrayList wrapper returned by
the Synchronized method. This makes your work easy, but may not be
what you need.

The synchronized wrapper makes individual operations thread safe, but
you might have code like this:

if(list.Count > 0)
Visitor v = list[0] as Visitor;

The problem with the above is that another thread might remove the
last visitor from the list between the time you check the Count
property and the time you retrieve the object with the [] indexer.
You'll get an exception.

The safest approach is to lock the list anytime you read or write:

lock(list.SyncRoot) {
// use the code above
}

.... and of course the safest approach is not going to be the most
performant approach.

Starting out, I would favor safety over performance, and run tests. In
most applications these locks won't kill performance. You can use
finer grained locks, or reader versus writer locks for more
throughput, but these add complexity.

If you do run into trouble I'd seriously consider storing the
information in a database. Relational databases excel at concurrency
management and fine grained locking.

Hope this helps,
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,020
Latest member
GenesisGai

Latest Threads

Top