Rogger296
Rogger296

Reputation: 147

Two threads reading same list but from different ends

i have a list , i need to traverse the list by two threads. One reading from top to bottom and other one from bottom to top. And when they intersect reading should stop.

For iterating over the list i can use ListIterator, but i am not able to think how these threads going to read from same list?

Upvotes: 1

Views: 1284

Answers (3)

TwoThe
TwoThe

Reputation: 14309

There is a simple way to solve this issue if you take into consideration that the total items processed by Thread A and the total items processed by Thread B will in the end be equal to the amount of items in the list.

So if you have a counter that decrements each time a thread wants to process the next element, you know you are done once the counter reaches zero.

public class MyThreadSyncer {
  protected final AtomicInteger elementCount;

  public MyThreadSyncer(final Collection c) {
    elementCount = new AtomicInteger(c.size());
  }

  public boolean canProcessNext() {
    return (this.elementCount.decrementAndGet() >= 0);
  }
}

Using this class each thread sets its own private counter (Thread A at 0, Thread B at size-1) and then checks like this:

if (this.threadSyncer.canProcessNext()) {
  this.theTasks[this.myPosition].process();

  this.myPosition += 1;  // this line in thread A
  this.myPosition -= 1;  // this line in thread B
}

Upvotes: 0

gati sahu
gati sahu

Reputation: 2641

you can partition the list that is one thread will read from 0 to half and second will read half+1 to last.

class PrintList implements Runnable{

    private List list = new ArrayList();
    public PrintList(List list){
        this.list = list;
    }


    @Override
    public void run() {
     if(Thread.currentThread().getName() != null && Thread.currentThread().getName().equalsIgnoreCase("thread1")){
         int mid =list.size()/2;
         for(int i = 0; i< mid;i++){
            // System.out.println("Thread 1 "+list.get(i));
         }
     }else if(Thread.currentThread().getName() != null && Thread.currentThread().getName().equalsIgnoreCase("thread2")){

         for(int i = mid; i<list.size(); i++){
             //System.out.println("Thread 2 "+list.get(i));
         }
     }  
    }   
}

Upvotes: 0

Thijs Steel
Thijs Steel

Reputation: 1272

Since the threads are only reading, there is no need to use a thread safe version of the list.

To make sure the threads stop reading when they intersect you will need to synchronize them, so before reading another item, they should check whether that item is available. A naive way to implement this is to store the current index in each thread and let the other thread have access to that index (make sure to synchronize that index). This would lead to a lot of overhead though.

A better idea is to work in batches. Divide the list in sections of for example 16 items. Then the threads can read the entire batch before needing to check for intersection.

Upvotes: 1

Related Questions