Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple threads working off the same list of strings, in java?

I'm trying to figure out the best way to have multiple threads working from the same list of strings. For example, say I have a list of words, and I want multiple threads to work on printing out each word on this list.

Here is what I came up with. The thread uses a while loop, and while the iterator has next, it prints out and removes it from the list.

import java.util.*;
public class ThreadsExample {

    static Iterator it;

    public static void main(String[] args) throws Exception {

        ArrayList<String> list = new ArrayList<>();

        list.add("comet");
        list.add("planet");
        list.add("moon");
        list.add("star");
        list.add("asteroid");
        list.add("rocket");
        list.add("spaceship");
        list.add("solar");
        list.add("quasar");
        list.add("blackhole");


        it = list.iterator();

        //launch three threads
        RunIt rit = new RunIt();

        rit.runit();
        rit.runit();
        rit.runit();

    }
}

class RunIt implements Runnable {

    public void run()
    {
        while (ThreadsExample.it.hasNext()) {
            //Print out and remove string from the list
            System.out.println(ThreadsExample.it.next());

            ThreadsExample.it.remove();
        }
    }

    public void runit() {
        Thread thread = new Thread(new RunIt());
        thread.start();
    }
}

This seems to work, although I get some Exception in thread "Thread-2" Exception in thread "Thread-0" java.lang.IllegalStateException errors during the run:

Exception in thread "Thread-1" Exception in thread "Thread-0"
java.lang.IllegalStateException at
java.util.ArrayList$Itr.remove(ArrayList.java:864) at
RunIt.run(ThreadsExample.java:44) at
java.lang.Thread.run(Thread.java:745) java.lang.IllegalStateException
at java.util.ArrayList$Itr.remove(ArrayList.java:864) at
RunIt.run(ThreadsExample.java:44) at
java.lang.Thread.run(Thread.java:745)

Am I doing this correctly or is there a better way to have multiple threads working on the same pool of strings?

like image 706
Andrio Avatar asked Dec 24 '22 20:12

Andrio


1 Answers

A better way to do this is to use a concurrent queue. The Queue interface is designed to hold elements in a structure prior to processing them.

    final Queue<String> queue = new ConcurrentLinkedQueue<String>();
    queue.offer("asteroid");

    ExecutorService executorService = Executors.newFixedThreadPool(4);

    executorService.execute(new Runnable() {
        public void run() {
            System.out.println(queue.poll());
        }
    });

    executorService.shutdown();
like image 59
M.K. Avatar answered Mar 15 '23 00:03

M.K.