1

There is one ArrayList with 1 million element and we are using two threads to read from this ArrayList. The first thread will read first half of the list and second thread will read the second half of list and I am using two threads to achieve this, but I don't see any difference in performance between using one thread and two threads.

I have written below program to achieve this, but I am not sure If this is the right way to implement and achieve this.

Can someone check if my code is correct or how I can fix the multithreading?

import java.util.ArrayList;
import java.util.List;

public class ThreadTask {

    public static void main(String[] args) throws InterruptedException {
        // TODO Auto-generated method stub

        List<Integer> list = new ArrayList<>();
        for(int i = 0; i <=1000000; i++){
            list.add(i);
        }

        Thread t1 = new Thread(new PrintList(list));
        Thread t2 = new Thread(new PrintList(list));
        t1.setName("thread1");
        t2.setName("thread2");
       long starttime = System.currentTimeMillis();
       System.out.println(starttime);
       t1.start();
       t2.start();
       t1.join(); 
       t2.join();
       long endtime = System.currentTimeMillis();
       System.out.println(endtime);
       System.out.println("Total time "+(endtime - starttime));     
    }


}

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")){

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

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

Also, If someone can help me on how can we implement it to make it generic to use more then to thread.

4
  • 1
    Nit: your list has 1,000,001 elements. Commented Jul 17, 2016 at 13:36
  • Most of the work in displaying number on the screen is in rendering the text as pixels. Your code doesn't change this in any way. Commented Jul 17, 2016 at 14:23
  • @PeterLawrey - I think I din't put the question in correct way. I am not at all focused on printing, I hae commented that part in my code, What I want to achieve is read 1 large arraylist using more then 1 thread , where each thread will read one segment of list concurrently, If you could suggect some way to achieve that. Commented Jul 18, 2016 at 5:07
  • Do you mean list.parallelStream().forEach(i -> doSomething(i));? This will use all the CPUs on your machine to process the elements of the list. Even simpler is Stream.range(0, 1000000).parallel().forEach(i -> ...) Commented Jul 18, 2016 at 6:45

2 Answers 2

4

System.out.println is synchronized internally (in order that you don't get mixing between the messages printed by multiple threads), so only one thread is actually printing at once.

Basically, it behaves like a single thread.

Sign up to request clarification or add additional context in comments.

1 Comment

Except, it has resource contention so using two threads is likely to be slower than just one thread.
1

Even if in reality System.out is synchronized, still you dont want to have manually initialized threads reading from your ArrayList. Plus I doubt that your end goal is the System.out. You should use a higher abstraction. Such abstraction can easily be present either through Java8 Stream API either by ExecutorServices.

Here is one example of paralelism with Java 8 api.

Arraylist toprint;

toPrint.parallelstream().forEach(DoSometing);

This will work in parallel threads.

If you use ExecutorService You can slice your Arraylist and pass each slice to a Callable to perform the work for you in a separate thread.

class Task implements Callable {
  List sublist;
  public Task(List sublist) {
       this.sublist = sublist;
  }

  public void call() {
     // do something
  }
}

ArrayList listToSlice;
List<List> slicedList;
ExecutorService executor = Executors.newFixedThreadPool(2);
for (List sublist:slicedList) {
   Future<Integer> future = executor.submit(new Task(sublist));
......
.......s on
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.