Domanda

File: Esempio1.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);


    }

}

File: Esempio2.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;
        }        
    }
}

Quando eseguo questo, viene visualizzato:

  

Tempo di esecuzione per un thread: 1219

     

Tempo di esecuzione per due thread: 281

o qualcosa di molto vicino.

Perché c'è una tale differenza? Perché dividerlo in due thread è più di due volte più veloce di eseguirlo direttamente?

È stato utile?

Soluzione

In realtà non stai aspettando che i thread finiscano affatto.

Una volta avviato un thread, è quindi necessario chiamare .join () su di esso per attendere il completamento. Quello che sta succedendo qui è che tutti i tuoi thread stanno iniziando e non appena è iniziato l'ultimo, lo cronometri e quindi calcoli il tempo di arresto. Ciò significa che i tuoi thread sono ancora in esecuzione in background.

Modifica: il motivo per cui il primo impiega così tanto tempo è perché stai facendo una serie di chiamate sincrone, mentre crei un thread e lo avvii genera un'attività asincrona.

Modifica 2: ecco un diagramma di sequenza del tovagliolo di ciò che accade nel primo test: http://www.websequencediagrams.com/cgi-bin / cdraw lz = TWFpbi0-RXhhbXBsZTE6IFRhc2sgc3RhcnRlZAphY3RpdmF0ZSAAGAgKACEILS0-TWFpbjogZG9uZQpkZQAYEgABWAABWAABgTFlMQo & amp;? s = tovagliolo

Ecco un diagramma di sequenza del tovagliolo di ciò che accade nel secondo test: http://www.websequencediagrams.com/cgi-bin/cdraw?lz = TWFpbi0tPkFub255bW91cyBUaHJlYWQ6IFN0YXJ0IEV4YW1wbGUxLnRhc2soKQoACSYyAAEuAAFdAAGBOwCCPjoAgyIGPk1haW46ICJIb3cgbG9uZyBkaWQgdGhhdCB0YWtlPyIKAINmEC0AKwhUYXNrcyBiZWdpbiB0byBmaW5pc2guLi4gKHNvbWUgbWF5IGhhdmUgZW5kZWQgZWFybGllcikK & amp; s = tovagliolo

Modifica 3: mi sono appena reso conto che il secondo diagramma di sequenza punta tutte le frecce sullo / stesso / thread. Sono infatti DIVERSI thread, ogni chiamata.

Altri suggerimenti

La chiamata start () su un thread ritorna immediatamente perché accoda il thread. Il thread stesso inizierà a essere eseguito in background qualche tempo dopo.

Ecco cosa ottengo con il tuo codice aggiungendo join ai thread:

  

Tempo di esecuzione per un thread: 566

     

Tempo di esecuzione per due thread: 294

Quindi le risposte precedenti sono corrette.

EDIT: ho aggiunto i join in questo modo. Puoi farlo meglio, ma non importa:

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

Devi unire ogni thread. Tuttavia, non perdi tempo ad aspettare in join () perché gli altri thread non sono bloccati. Se il thread ha terminato l'esecuzione, prima di chiamare per unirti, continua con il thread successivo.

Inoltre, cosa significa il tuo ultimo commento?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top