Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/367.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 线程的性能开销_Java_Multithreading - Fatal编程技术网

Java 线程的性能开销

Java 线程的性能开销,java,multithreading,Java,Multithreading,我试图通过添加线程来执行并发任务来提高应用程序的性能。我得到的结果让我非常困惑,让我觉得有某种线程相关的开销,我不知道。下面是同一代码的两个副本,一个使用线程,另一个不使用。不使用线程的运行速度是使用线程的运行速度的四倍。我正在使用我的设备进行测试,这是一款带有四处理器的三星note 4。任何见解都将受到高度欢迎 谢谢 水煤浆 public void testThreads()引发InterruptedException{ startMilli=System.currentTimeMillis(

我试图通过添加线程来执行并发任务来提高应用程序的性能。我得到的结果让我非常困惑,让我觉得有某种线程相关的开销,我不知道。下面是同一代码的两个副本,一个使用线程,另一个不使用。不使用线程的运行速度是使用线程的运行速度的四倍。我正在使用我的设备进行测试,这是一款带有四处理器的三星note 4。任何见解都将受到高度欢迎

谢谢

水煤浆

public void testThreads()引发InterruptedException{
startMilli=System.currentTimeMillis();
线程t1=新线程(){
公开募捐{
load1();
}
};
线程t2=新线程(){
公开募捐{
load2();
}
};
t1.start();
t2.start();
t1.join();
t2.连接();
//load1();
//load2();
stopMilli=System.currentTimeMillis();
diffMilli=stopMilli-startMilli;
startMilli=System.currentTimeMillis();
}
公共无效载荷1(){
List list1=新的ArrayList();
对于(i=0;i一般指南:

通过使用线程来提高应用程序的性能可能非常棘手;线程太少,您的性能可能会有所下降;线程太多,线程的开销会侵蚀从程序并发性中获得的好处

要使其正确运行,您必须设置尽可能多的线程,并确保您的程序能够很好地分解为这么多线程。如果您允许程序在各种硬件上运行,那么要正确运行可能会很困难


线程池的发明就是为了提供帮助。广义上说,它们的线程数正好适合程序运行的硬件,并且它们允许您提交大量小的并发任务以供执行,而无需为每个任务设置新线程。因此,您的程序可以在各种不同的硬件上运行良好不必太担心它。

我不确定,但我认为操作系统内存管理是您的问题所在。在第一种方法中,您在每个列表中同时添加100000个元素。因此,两个线程同时调用调整大小操作,这可能会锁定内存,同时为更大的列表找到新的空间,使在第二种方法中,按顺序添加200000个元素,因此不会发生两个同时调整大小的操作,也不会锁定内存

我对更大的集合进行了测试。数组比列表实现稍微快一点

下面是总计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毫秒

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);
}
int范围=100000000;
公共静态void main(字符串[]args)引发InterruptedException{
测试m=新测试();
m、 testThreads1();//m.testThreads();
}
public void testThreads()引发InterruptedException{
long startMilli=System.currentTimeMillis();
线程t1=新线程(){
公开募捐{
load1();
}
};
线程t2=新线程(){
公开募捐{
load1();
}
};
线程t3=新线程(){…}
线程t4=新线程(){…}
t1.start();
t2.start();
t3.start();
t4.开始();
t1.join();
t2.连接();
t3.join();
t4.join();
long stopMilli=System.currentTimeMillis();
System.out.println(stopMilli-startMilli);
}
公共无效载荷1(){
List list1=新的ArrayList();
//int[]arr=new int[range];//根据线程更改大小#

对于(int i=0;iI删除了我的错误答案。我测试了一些理论。将
ArrayList
更改为
int[]
。这将大大提高性能。很可能是因为您没有做足够的工作来证明使用线程的合理性。也就是说,启动线程所需的时间比向列表中添加100000个项目所需的时间更长。将其更改为10000000个项目,然后再次运行测试。
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);
}