왜 두 개의 Java 스레드 (경우에 따라)가 하나보다 두 배 이상 빠른 이유는 무엇입니까?

StackOverflow https://stackoverflow.com/questions/1447261

문제

파일 : example1.java

public class Example1 implements Runnable {

    public void run() {
        for(int i = 0; i < 100000000; i++) {
            int x = 5;
            x = x * 4;
            x = x % 3;
            x = x + 9000;
            x = x * 923;
        }
    }

    public static void task() {
        for(int i = 0; i < 100000000; i++) {
            int x = 5;
            x = x * 4;
            x = x % 3;
            x = x + 9000;
            x = x * 923;
        }
        for(int i = 0; i < 100000000; i++) {
            int x = 9;
            x = x * 2;
            x = x % 4;
            x = x + 3241;
            x = x * 472;
        }
    }

    public static void main(String[] args) {

        long startTime = System.currentTimeMillis();
            Example1.task();
            Example1.task();
            Example1.task();
            Example1.task();
            Example1.task();
        long stopTime = System.currentTimeMillis();
        long runTime = stopTime - startTime;
        System.out.println("Run time for one thread: " + runTime);


        startTime = System.Example1();
            (new Thread(new Example1())).start();
            (new Thread(new Example2())).start();
            (new Thread(new Example1())).start();
            (new Thread(new Example2())).start();
            (new Thread(new Example1())).start();
            (new Thread(new Example2())).start();
            (new Thread(new Example1())).start();
            (new Thread(new Example2())).start();
            (new Thread(new Example1())).start();
            (new Thread(new Example2())).start();
        stopTime = System.currentTimeMillis();
        runTime = stopTime - startTime;
        System.out.println("Run time for two threads: " + runTime);


    }

}

파일 : example2.java

public class Example2 implements Runnable {

    public void run() {
        for(int i = 0; i < 100000000; i++) {
            int x = 9;
            x = x * 2;
            x = x % 4;
            x = x + 3241;
            x = x * 472;
        }        
    }
}

이것을 실행하면 출력이 있습니다.

하나의 스레드에 대한 시간 : 1219

두 스레드에 대한 시간 : 281

또는 아주 가까운 것.

왜 그런 차이가 있습니까? 두 스레드로 나누는 것이 왜 직접 실행하는 것보다 두 번 이상 빠르게 진행됩니까?

도움이 되었습니까?

해결책

당신은 실제로 스레드가 전혀 끝날 때까지 기다리지 않습니다.

스레드를 시작하면 스레드가 완료되기를 기다리려면 .join ()을 호출해야합니다. 여기서 일어나는 일은 모든 스레드가 시작되고 마지막 스레드가 시작 되 자마자 시계를 치고 정지 시간을 계산한다는 것입니다. 이것은 당신의 스레드가 여전히 백그라운드에서 실행되고 있음을 의미합니다.

편집 : 첫 번째 시간이 오래 걸리는 이유는 일련의 동기 호출을하고 스레드를 만들고 시작하면 비동기 작업을 시작하기 때문입니다.

편집 2 : 첫 번째 테스트에서 발생하는 일에 대한 냅킨 시퀀스 다이어그램이 있습니다.http://www.webestenceationiagrams.com/cgi-bin/cdraw?lz=twfpbi0-rxhhbxzte6ifrhc2sgc3rhcnrlzaphy3rpdmf0zsaagagkaceils0-twfbjogzg9uzqpkzqwwaabgwaabgwaabgwaabgwaabgwaabgwaabgwaabgwaabgwaabgwaabg

다음은 두 번째 테스트에서 발생하는 일에 대한 냅킨 시퀀스 다이어그램입니다.http://www.websequencediagrams.com/cgi-bin/cdraw?lz=TWFpbi0tPkFub255bW91cyBUaHJlYWQ6IFN0YXJ0IEV4YW1wbGUxLnRhc2soKQoACSYyAAEuAAFdAAGBOwCCPjoAgyIGPk1haW46ICJIb3cgbG9uZyBkaWQgdGhhdCB0YWtlPyIKAINmEC0AKwhUYXNrcyBiZWdpbiB0byBmaW5pc2guLi4gKHNvbWUgbWF5IGhhdmUgZW5kZWQgZWFybGllcikK&s=napkin

편집 3 : 방금 두 번째 시퀀스 다이어그램이 모든 화살표를 / 동일한 / 스레드로 가리킨다는 것을 깨달았습니다. 그들은 실제로 다른 스레드, 각 호출입니다.

다른 팁

스레드에서 start ()가 스레드를 큐에 넣기 때문에 즉시 돌아옵니다. 스레드 자체는 얼마 후에 백그라운드에서 실행되기 시작합니다.

다음은 스레드에 조인을 추가하는 코드를 사용하여 얻는 것입니다.

하나의 스레드에 대한 시간 : 566

두 개의 스레드에 대한 시간 : 294

따라서 이전 답변이 정확합니다.

편집 : 나는이 방법으로 결합을 추가했습니다. 더 잘 할 수는 있지만 중요하지 않습니다.

    Thread[] t = new Thread[10];
    (t[0] = new Thread(new Example1())).start();
    (t[1] = new Thread(new Example2())).start();
    (t[2] = new Thread(new Example1())).start();
    (t[3] = new Thread(new Example2())).start();
    (t[4] = new Thread(new Example1())).start();
    (t[5] = new Thread(new Example2())).start();
    (t[6] = new Thread(new Example1())).start();
    (t[7] = new Thread(new Example2())).start();
    (t[8] = new Thread(new Example1())).start();
    (t[9] = new Thread(new Example2())).start();

    for (Thread t1: t) {
        try {
            t1.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

각 스레드에 가입해야합니다. 그러나 다른 스레드가 차단되지 않기 때문에 Join ()에서 대기하는 시간을 낭비하지 않습니다. 스레드가 완료되면 가입하기 전에 실행을 완료하면 다음 스레드로 계속 진행됩니다.

또한 마지막 의견은 무엇을 의미합니까?

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top