同时使用两个线程从arraylist读取

时间:2016-07-17 13:12:23

标签: java multithreading

有一个ArrayList有100万个元素,我们使用两个线程来读取这个ArrayList。第一个线程将读取列表的前半部分,第二个线程将读取列表的后半部分,我使用两个线程来实现此目的,但我没有看到使用一个线程和两个线程之间的性能差异。

我已经编写了以下程序来实现这一目标,但我不确定这是否是实现和实现这一目标的正确方法。

有人可以检查我的代码是否正确或我如何修复多线程?

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

此外,如果有人可以帮助我,我们如何实现它以使其通用以使用更多的线程。

2 个答案:

答案 0 :(得分:4)

System.out.println在内部同步(以便您不会在多个线程打印的消息之间混合),因此实际上只有一个线程实际打印。

基本上,它的行为类似于单个线程。

答案 1 :(得分:1)

即使实际上System.out已同步,您仍然不希望手动初始化从ArrayList读取的线程。另外,我怀疑你的最终目标是System.out。你应该使用更高的抽象。这种抽象可以通过ExecutorServices通过Java8 Stream API轻松呈现。

以下是使用Java 8 api进行并行的一个例子。

Arraylist toprint;

toPrint.parallelstream().forEach(DoSometing);

这将在并行线程中工作。

如果使用ExecutorService您可以对Arraylist进行切片并将每个切片传递给Callable,以便在单独的线程中为您执行工作。

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
}