Thread de programmation Java exécutable

Qu'est-ce que le fil

** Thread ** est une unité de flux qui exécute le traitement </ font>. Pour résumer le fonctionnement de l'ordinateur

Vous pouvez imaginer cette série de traitements comme Thread.


Fil unique et multi fil

Filetage unique (figure de gauche): fil qui se termine par un seul processus Multi-thread (figure de droite): un thread dans lequel plusieurs threads s'exécutent en même temps

qiita01 (2).png

Vous pouvez l'imaginer comme ça.

Avantages du multithreading

Il peut traiter plus rapidement qu'un seul thread.

For example) Lorsque vous travaillez dans Microsoft Word, la vérification orthographique est effectuée et le nombre de mots est affiché en même temps. C'est la vraie valeur du multithreading.


Fonctionnement de base de Thread

  • Implémentez l'interface Runnable dans la classe.

Runnable.java


classe nom de classe implémente Runnable{
  public void run(){
    /*Ecrire le processus*/
  }
}

--Passez et déclarez une classe qui implémente Runnable en tant qu'argument du constructeur Thread.

Thread.java


Thread thread = new Thread(Variable de type de classe);

La référence du constructeur de type Thread est la suivante.

Reference-Thread-Constructor(référence)


Thread
public Thread(Runnable target)
  • Fil de départ Vous pouvez exécuter la méthode run () dans la classe avec la méthode start () </ font>.

ThreadStart.java


thread.start();

--Vérifiez si Thread est terminé Utilisez la méthode join () </ font> de Thread.

  • Cette fois, nous supposerons qu'il y a plusieurs threads dans le tableau.

Join.java


try{
    for(int i=0; i<thread.length; i++){
        thread[i].join();
    }
} catch(InterruptedException ie){
    ie.printStackTrace();
}

Différence entre avec et sans threads

Ajoutez 1 à la somme des variables. Vérification du temps d'exécution avec et sans threads pour un programme qui se répète 1000000000 fois.

Sans fils

NoThread.java


import java.util.Date;
import java.math.BigInteger;

public class NoThread{
    private static BigInteger N = new BigInteger("1000000000");
    private static BigInteger sum = BigInteger.ZERO;

    public static void main(String[] args){
        long start_time = new Date().getTime();
        calculate();
        long end_time = new Date().getTime();
        output(start_time, end_time);
    }

    public static void calculate(){
        BigInteger i = BigInteger.ZERO;
        while(!i.equals(N)){
            sum = sum.add(BigInteger.ONE);   // sum += i
            i = i.add(BigInteger.ONE);       // i++
        }
    }

    public static void output(long s, long e){
        System.out.println("Sum: "+sum);
        System.out.println("total time: "+(e-s)+"ms");
    }
}

Résultat de l'exécution: スクリーンショット 2019-06-08 0.06.53.png

Le nombre de fils Temps d'exécution
Aucun 46371 ms
  • Le temps de traitement n'est pas toujours constant.

S'il y a un fil

Cette fois, spécifiez le nombre de threads dans l'argument lors de l'exécution.

ThreadRun.java


import java.math.BigInteger;
import java.util.Date;

public class ThreadRun{
    private static BigInteger N = new BigInteger("1000000000");
    private static BigInteger sum = BigInteger.ZERO;

    public static void main(String[] args){
        int num_threads = Integer.parseInt(args[0]);
        BigInteger range = N.divide(new BigInteger(args[0]));

        ThreadRunnable[] tr = new ThreadRunnable[num_threads];
        Thread[] t = new Thread[num_threads];

        BigInteger low = BigInteger.ONE;
        BigInteger high = low.add(range);
        long start_time = new Date().getTime();

        for(int i=0; i<num_threads-1; i++){
            tr[i] = new ThreadRunnable(low, high);
            t[i] = new Thread(tr[i]);
            t[i].start();

            low = high.add(BigInteger.ONE);
            high = low.add(range);
        }
        tr[num_threads-1] = new ThreadRunnable(low, high);
        t[num_threads-1] = new Thread(tr[num_threads-1]);
        t[num_threads-1].start();

        try{ // check whether threads finished
            for(int i=0; i<num_threads; i++){
                t[i].join();
            }
        } catch(InterruptedException ie){
            ie.printStackTrace();
        }

        for(int i=0; i<num_threads; i++){
            sum = sum.add(tr[i].getSum());
        }
        
        long end_time = new Date().getTime();
        System.out.println("Sum: "+sum);
        System.out.println("total time: "+(end_time-start_time)+"ms");
    }

    protected static class ThreadRunnable implements Runnable{
        private BigInteger sum_temp;
        private BigInteger low, high;
        public ThreadRunnable(BigInteger l, BigInteger h){
            this.low = l;
            this.high = h;
            this.sum_temp = BigInteger.ZERO;
        }

        @Override
        public void run(){
            while(!low.equals(high)){
                sum_temp = sum_temp.add(BigInteger.ONE);  // sum_temp += low
                low = low.add(BigInteger.ONE); // low++;
            }
        }

        public BigInteger getSum(){
            return sum_temp;
        }
    }
}

Résultat de l'exécution: スクリーンショット 2019-06-08 0.07.05.png S'il y a un fil,

Le nombre de fils Temps d'exécution
8 26840 ms
16 26462 ms
  • Le temps de traitement n'est pas toujours constant.

Résumé

Le temps de traitement est plus court avec les threads que sans threads. Une utilisation efficace des threads peut faire gagner beaucoup de temps. Cependant, si vous augmentez trop le nombre de threads, le temps d'exécution augmentera, il est donc important de spécifier un nombre approprié de threads </ font>.

Recommended Posts