0

I want to create two threads that one adds elements into ArrayList (or vector) and the other removes elements from this list concurrently. For example, if thread1 adds 20 elements into the list, then thread2 starts removing at the same time until total elements are removed, but these two threads must be work at the same time.

I wrote a producer (adding to the list) thread. In this thread, when the number of elements added to the list is greater than 5 or any number, so new thread must be started but in here I am stuck. I will mark the point that I was stuck.

public class Test{

public static void main(String[] args) {

    Data d = new Data();
    Thread t = new Thread(new producer(d));
    t.start();
}

}
class producer implements Runnable{

Data d;
Data d2;
Object lck;

public producer(Data dd)
{
    d=dd;
}
@Override
public void run()
{
    for (int i=0;i<100;++i ) {
        synchronized (d){
            d.a.add(i);
            // if i is greater than 5,
            // start consumer thread 
            // which remove elements from ArrayList.
            // but how ??
            Thread t = new Thread(new Runnable(){
                @Override
                public void run()
                {
                    //if(d.a.isEmpty())
                    //wait the adder thread 
                }
            });
            t.start();      
        }
    }
}

}
class Data{
  ArrayList<Integer> a; // or vector
  public Data()
  {
      a = new ArrayList<>();
  } 
}

How can I implement a remover thread that removes all elements in the list with the same time with adder thread and synchronize them?

tango-1
  • 330
  • 1
  • 10

2 Answers2

0

You can try concurrent package of java . https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CopyOnWriteArrayList.html

You are using synchronized block in thread which will not help in this case. Method in collection or shared data should be synchronized as it will be accessed by multiple thread

  • CopyOnWriteArrayList will be too costly,(because mutations vastly outnumbered traversal operations) In your case I would used Synchronized block for the operations and Collections.synchronizedList.Usefull links:https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CopyOnWriteArrayList.html and https://stackoverflow.com/questions/28979488/difference-between-copyonwritearraylist-and-synchronizedlist – mariq vlahova Oct 01 '21 at 09:27
0

In your code, you are creating 100 consumer thread in producer class within synchronized block. This is not efficient way to utilize parallelism using multi-threading. You are creating one thread for one data to be consumed. Once the data is consumed your thread will be in DEAD state and will not be useful to consume other incoming data, this is wastage of resource as well as requires more time to solve problem.

Take reference of below code to solve your consumer producer problem.

import java.util.*;

class Data {
    final List<Integer> a;

    public Data() {
        a = new ArrayList<>();
    }
}

public class Producer implements Runnable {

    private final Data data;

    public Producer(Data data) {
        this.data = data;
    }

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            synchronized (data) {
                data.a.add(i);
            }
        }
    }
}

public class Consumer implements Runnable {

    private Data data;
    private boolean isThreadEnabled = true;

    public Consumer(Data data) {
        this.data = data;
    }

    @Override
    public void run() {
        while (isThreadEnabled) {
            synchronized (data) {
                if (!data.a.isEmpty()) {
                    System.out.println(data.a.remove(0));
                }
            }
        }
    }

    public void stopConsumer() {
        isThreadEnabled = false;
    }
}

public class ThreadsMain {

    public static void main(String args[]) {

        try {
            Data data = new Data();
            Consumer consumerRunnable = new Consumer(data);
            Thread producer = new Thread(new Producer(data));
            Thread consumer = new Thread(consumerRunnable);

            producer.start();
            consumer.start();
            producer.join();

            try {
                //wait for consumer to consume data and then stop the thread
                Thread.sleep(1000);
                consumerRunnable.stopConsumer();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

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

}
Joy
  • 394
  • 2
  • 9