在两个线程之间共享一个ArrayList?

Jen*_*aiz 5 java concurrency multithreading arraylist

所以我有两个线程在运行,其中一个线程应该从用户获取信息,另一个线程假设使用用户提供的信息,如下所示:

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

}
Run Code Online (Sandbox Code Playgroud)

第二个帖子:

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();     
}
}
Run Code Online (Sandbox Code Playgroud)

我想这样做的是采取一切输入用户里面输入UserRequest对象,并推入ArrayListPoller对象,以便它可以在新价值的"工作"为好.我看过一些类似BlockingQueue但我不希望Thread等待另一个,因为除了这些数据共享之外,他们还需要完成其他任务.我该怎么做呢?

小智 5

既然你已经使用了动词'push'和'poll',那么你似乎正在寻找一个Queue不是a List.

因此,我认为你正在寻找ConcurrentLinkedQueue,记录在这里.

它允许您让UserRequest对象提供它和您的Poller对象来使用它.

虽然看起来你的Poller对象会有相当高的CPU消耗,因为open while没有任何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();
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

此代码需要进行一些更改才能运行,但它包含您需要的所有内容.它的作用非常简单:它一直保持轮询,直到没有剩余元素为止.一旦发生这种情况,Poller对象会询问它当前Thread是否处于睡眠状态,因为它没有任何意义可以在没有元素的情况下运行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
      }
    }
  }
Run Code Online (Sandbox Code Playgroud)

如果你注意到,我只是notifyAll给你的UserRequest班级打了一个电话.为什么?很简单:notifyAll唤醒所有wait荷兰国际集团ThreadS的正是所有PollerS不使用的元素都在做.

一旦它被调用,Pollers将唤醒,检查它们的颜色Queue是否有元素并与它们一起工作.如果Queue它没有元素,它们将再次睡眠,直到再次UserRequest唤醒它们,依此类推.