有一个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));
}
}
}
}
此外,如果有人可以帮助我,我们如何实现它以使其通用以使用更多的线程。
答案 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
}