Sharing an ArrayList between two threads?

arraylist, concurrency, java, multithreading

Solution

Since you've used the verb 'push' and 'poll', it seems you are looking for a `Queue` not a `List`.

Therefore, I think you're looking for the `ConcurrentLinkedQueue`, documented here.

It allows you to have your `UserRequest` objects feed it and your `Poller` objects to consume it.

Though it seems your `Poller` objects will have quite a high CPU consuption because of the open `while` not having any `wait`:

public class Poller implements Runnable {
  Queue<String> colors = new ConcurrentLinkedQueue<String>();

  public void poll() {
    while(this.colors.isEmpty()){
      Thread.currentThread().wait();
    }

    String color = this.colors.poll();

    while(color != null) {
      if(color == "") {
        //do work

      } else {
        //do work
      }

      color = this.colors.poll();
    }
  }

  @Override
  public void run() {
    colors.offer("Violet");
    colors.offer("Green");
    colors.offer("Yellow");
    colors.offer("Orange");

    while(true) {

      this.poll();
    }
  }
}

this code needs some changes to run but it contains pretty much everything you need. What it does is very simple: It keeps polling until there are no elements left. Once that happens, the `Poller` object asks it's current `Thread` to sleep, since there's no point for it to run without elements in the `Queue`.

public class UserRequest implements Runnable {

  @Override
  public void run() {
    String request;
    Scanner input = new Scanner(System.in);

    while(true) {
      System.out.println("Please enter request:");
      request = input.nextLine();

      try {
        //do something

      } catch(IOException e) {
        e.printStackTrace();

      } finally {
        this.notifyAll(); // Notifies all sleeping threads to wake up
      }
    }
  }

If you notice, I've only added a `notifyAll` call to your `UserRequest` class. Why? Very simple: `notifyAll` wakes all `wait`ing `Thread`s which is exactly what all `Poller`s without elements are doing.

Once it's called, the `Poller`s will wake, check if their color `Queue` has elements and work with them. If the `Queue` has no elements, they will sleep again until a `UserRequest` wakes them up again and so on and so forth.

Problem

So I have two threads running where one of them is supposed to get information from the user and the other thread is suppose to work with information supplied by users as follows: ``` public class UserRequest implements Runnable { @Override public void run() { // TODO Auto-generated method stub String request; Scanner input = new Scanner(System.in); while(true) { System.out.println("Please enter request:"); request = input.nextLine(); try { //do something } catch(IOException e) { e.printStackTrace(); } } } ``` And second thread: ``` public class Poller implements Runnable { ArrayList<String> colors = new ArrayList<String>(); public void poll() { for(String color : colors) { if(color == "") { //do work } else { //do work } } } @Override public void run() { colors.add("Violet"); colors.add("Green"); colors.add("Yellow"); colors.add("Orange"); while(true) poll(); } } ``` What I would like to do is take whatever input the user entered inside the `UserRequest` object and push into the `ArrayList` in `Poller` object so it can "work" on the new value as well. I have looked at some thing like `BlockingQueue` but I don't want either Thread to wait for the other since they have other tasks they need to accomplish in addition to this sharing of data. How can I go about doing this ?

Original source

Related problems