views:

163

answers:

4

I need help in ArrayList. I have an arraylist of strings. I am looping through this list and sending them to the output stream one after the other. While I am looping through the list and sending them, it is possible that another thread will be adding some elements to it. After an element is sent, it must be removed from the list as well.

How can I achieve this successfully?

+9  A: 

If the items are added to the end of the list, you would better use a Queue instead. There are various thread-safe implementations available in Java5 and above, including ConcurrentLinkedQueue and LinkedBlockingQueue.

In general, the former is the preferable choice, unless you want a bounded blocking queue, in which case use the latter.

Péter Török
An `ArrayBlockingQueue` is not really appropriate since it's a fixed-size collection (i.e. its capacity cannot be changed after construction).
BalusC
@BalusC, just fixed that one while you were typing your comment :-)
Péter Török
Funny to see how it get much more upvotes because it's posted a minute before, while you quickly edited `ConcurrentLinkedQueue` in only a minute after my answer :)
BalusC
@BalusC, believe me, I was not copying your answer. I agree though that yours is as good as mine (or almost - I believe mine contains slightly more information, but of course I may be biased :-) Definitely not such a difference which would justify so many more upvotes - I don't consider it _deserved_ for such a fairly trivial answer anyway, but life is not always fair on SO... one way or the other.
Péter Török
+6  A: 

Use the right data structure for the job. Use a ConcurrentLinkedQueue. Here's how it describes itself in its javadoc:

An unbounded thread-safe queue based on linked nodes. This queue orders elements FIFO (first-in-first-out). The head of the queue is that element that has been on the queue the longest time. The tail of the queue is that element that has been on the queue the shortest time. New elements are inserted at the tail of the queue, and the queue retrieval operations obtain elements at the head of the queue. A ConcurrentLinkedQueue is an appropriate choice when many threads will share access to a common collection.

BalusC
It should be known a ConcurrentLinkedQueue does not wait on the Queue not being empty. Meaning any poll will return null where a LinkedBlockingQueue will wait on poll. Not sure which the OP requires.
John V.
A: 

Assuming this is homework, I'll just give some hints.

  • both threads can synchronize on the list to reserve exclusive access
  • the remove() method returns the object removed
  • you can remove from the start of the list while adding to the end

This should help you on your way, it always helps if you post what you have so far so we can base out advice on your code.

rsp
+2  A: 

I advise to use some implementation of BlockingQueue as ArrayList is not designed for concurrent modifications:

class Producer implements Runnable {

  private BlockingQueue<String> queue;

  public Producer(BlockingQueue<String> queue) {
    this.queue = queue;
  }

  public void run() {
    try {
      queue.put("foo");
      queue.put("done");
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
  }
}

class Consumer implements Runnable {

  private final BlockingQueue<String> queue;

  public Consumer (BlockingQueue<String> queue) {
    this.queue = queue;
  }

  public void run() {
    try {
      String value = queue.take();
      while (!value.equals("done")) {
        value = queue.take();
        System.out.println(value);
      }
    } catch (InterruptedException e) {
       e.printStackTrace();
    }
  }
}

public class Main {
  public static void main(String[] args) throws Exception {
    BlockingQueue<String> queue = new LinkedBlockingQueue<String>();
    Thread producer = new Thread(new Producer(queue));
    Thread consumer = new Thread(new Consumer(queue));
    producer.start();
    consumer.start();
    producer.join();
    consumer.join();
  }
}
Vitalii Fedorenko
Thanks to everyone for all your replies
kap
Nice demonstration code there.
James P.