我正在尝试通过添加线程来执行并发任务来提高应用程序的性能。我得到的结果对我来说非常混乱,让我觉得有一些线程相关的开销,我不知道。下面是相同代码的两个副本,除了一个使用线程而另一个不使用。不使用线程的线程比使用线程的线程快四倍。我正在使用我的设备进行测试,这是带有四核处理器的三星note 4。任何见解都将受到高度欢迎。
谢谢,
CWM
public void testThreads() throws InterruptedException {
startMilli = System.currentTimeMillis();
Thread t1 = new Thread() {
public void run() {
load1();
}
};
Thread t2 = new Thread() {
public void run() {
load2();
}
};
t1.start();
t2.start();
t1.join();
t2.join();
// load1();
// load2();
stopMilli = System.currentTimeMillis();
diffMilli = stopMilli - startMilli;
startMilli = System.currentTimeMillis();
}
public void load1() {
List<Integer> list1 = new ArrayList<Integer>();
for(i = 0; i<100000; i++) {
list1.add(i);
}
}
public void load2() {
List<Integer> list2 = new ArrayList<Integer>();
for(j = 100000; j<200000; j++){
list2.add(j);
}
}
public void testThreads() throws InterruptedException {
startMilli = System.currentTimeMillis();
load1();
load2();
stopMilli = System.currentTimeMillis();
diffMilli = stopMilli - startMilli;
startMilli = System.currentTimeMillis();
}
public void load1() {
List<Integer> list1 = new ArrayList<Integer>();
for(i = 0; i<100000; i++) {
list1.add(i);
}
}
public void load2() {
List<Integer> list2 = new ArrayList<Integer>();
for(j = 100000; j<200000; j++){
list2.add(j);
}
}
答案 0 :(得分:0)
我不确定,但我认为操作系统内存管理是你的问题所在。在第一种方法中,您将在每个List中同时添加100000个元素。因此两个线程同时调用resize操作,这可能会锁定内存,同时为较大的List找到新的空间,使其他线程等待。在第二种方法中,顺序添加200000个元素,因此不会发生两个同时的调整大小操作并且没有锁定存储器。
我为更大的套装进行了测试。 Array比List实现稍快。
以下是总计100000000次内存访问操作的结果
using array/arraylist
thread x4: 83 / 20000 ms // each thread got 25000000 size chunk
thread x2: 75 / 22000 ms // each thread got 50000000 size chunk
main thread: 146/ 25800 ms // main thread processed all elements in one arraylist
但是当我用range/2
个元素填充两次arraylist时,时间从25800减少到10100 ms。
int range = 100000000;
public static void main(String[] args) throws InterruptedException {
TEST m = new TEST();
m.testThreads1(); // m.testThreads();
}
public void testThreads() throws InterruptedException {
long startMilli = System.currentTimeMillis();
Thread t1 = new Thread() {
public void run() {
load1();
}
};
Thread t2 = new Thread() {
public void run() {
load1();
}
};
Thread t3 = new Thread() {...}
Thread t4 = new Thread() {...}
t1.start();
t2.start();
t3.start();
t4.start();
t1.join();
t2.join();
t3.join();
t4.join();
long stopMilli = System.currentTimeMillis();
System.out.println(stopMilli - startMilli);
}
public void load1() {
List<Integer> list1 = new ArrayList<Integer>();
// int[] arr = new int[range]; // change size according to thread #
for(int i = 0; i<range/2; i++) {
list1.add(i);
// arr[i]=i;
}
}
public void testThreads1() throws InterruptedException {
long startMilli = System.currentTimeMillis();
/* 2 load1 call for `range/2` elements performes better than 1 call for `range` elements */
load1();
load1();
long stopMilli = System.currentTimeMillis();
System.out.println(stopMilli - startMilli);
}