graczun
graczun

Reputation: 582

3 threads with access to 1 object in java

I want to create a static arrayList for communication between 3 threads: 1. thread will add some data to list; 2. thread will remove data from list; 3. thread (timer every 3 sec) will check if size of list equals 0, and if no print all object of this list.

I'm wondereing what would happen if more than 1 thread will try to access this list at same time (for example timer will check size of list at same time when second thread will be removeing object from list). I guess that i have to synchronize this list, but have no idea how to do that. Can you give me some advise?

Upvotes: 0

Views: 209

Answers (5)

Narendra Pathai
Narendra Pathai

Reputation: 41935

I'm wondereing what would happen if more than 1 thread will try to access this list at same time

Firstly ArrayList is not thread-safe, so you should not use it directly.

One possibility is to use Collections.synchronizedList(...); which provides you thread safety but will hamper concurrency.

Your requirement seems to be like a Queue, so you should use BlockingQueue for that, e.g LinkedBlockingQueue which is thread-safe.

NOTE:

Compound operations on list will still be unsafe if you use Collections.synchronizedList(...).

Upvotes: 3

Jason Braucht
Jason Braucht

Reputation: 2368

ArrayList is not thread-safe. You will need to handle the synchronization by yourself or the results will be unpredictable.

As suggested in the related question: How do I make my arraylist thread safe you could use Collections.synchronizedList(...) to obtain a thread-safe version of your List

The javadoc gives an example of how to utilize the List returned by that method.

List list = Collections.synchronizedList(new ArrayList());
...
synchronized (list) {
    Iterator i = list.iterator(); // Must be in synchronized block
    while (i.hasNext())
        foo(i.next());
} 

Other solutions have already suggested this, but using this approach has a potential performance penalty since the synchronization blocks concurrent access to the List. This will ultimately limit the rate at which you are able to add & remove data from the backing List.

Upvotes: 2

Cruncher
Cruncher

Reputation: 7812

Better yet, using concurrency primitives (wait, notify, and synchronized) you can have the printing thread wait, and only wake up after one of the other threads actually changed the ArrayList. This has the advantage of not printing when there's no change, and being woken up immediately when a change happens. You may still get false wake-ups, but can be coded around if it's a problem.

In printing thread:

synchronized(lock)
{ 
    while(true/*or some boolean to indicate you're done*/)
    {
        lock.wait();
        //print list
    }
}

In a thread that edits the list:

synchronized(lock)
{
    //modify list
    lock.notify();
}

You can also do lock.wait(3000); to print after 3 seconds anyway even if no change happens.

Upvotes: 1

Keerthivasan
Keerthivasan

Reputation: 12880

This code snippet will help you in the right direction

//have a lock Object
private static final Object lock = new Object();
// your list
private static List list = null

//synchronized on lock object. this will allow only one thread at a time
synchronized(lock){
//access,add to, remove from list
}

By this way, you can make sure there is only one thread at a time accessing your list

Upvotes: 1

Konstantin Yovkov
Konstantin Yovkov

Reputation: 62864

You can use

List myList = Collections.synchronizedList(new ArrayList());

Upvotes: 2

Related Questions