Maison  >  Article  >  Java  >  Priorité du thread Java

Priorité du thread Java

(*-*)浩
(*-*)浩avant
2019-09-26 15:37:212768parcourir

Priorité du thread Java

Priorité du thread Java

Dans la classe Thread, les attributs suivants sont utilisés pour représenter la priorité.

private int priority;

Nous pouvons définir une nouvelle priorité via setPriority(int newPriority) et obtenir la priorité du thread via getPriority().

Quelques informations permettent de conclure à travers l'exemple suivant : la priorité par défaut des threads Java est 5.

public static void main(String[] args) {
    Thread thread = new Thread();
    System.out.println(thread.getPriority());
}
// 打印结果:5

En fait, c'est complètement faux. Je viens de voir la surface. Regardez l'exemple ci-dessous. Nous avons changé la priorité du fil de discussion actuel à 4 et avons constaté que la priorité du fil de discussion enfant est également de 4. .

public static void main(String[] args) {
    Thread.currentThread().setPriority(4);
    Thread thread = new Thread();
    System.out.println(thread.getPriority());
}

// 打印结果:4

C'est une gifle. Si la priorité par défaut d'un fil est de 5, notre fil de discussion nouvellement créé n'a pas de priorité définie. Elle devrait être de 5, mais elle est en fait de 4. Jetons un coup d'œil au code source de la priorité d'initialisation du Thread.

Thread parent = currentThread();
this.priority = parent.getPriority();

Il s'avère que la priorité par défaut d'un thread est d'hériter de la priorité du thread parent. Dans l'exemple ci-dessus, nous définissons la priorité du thread parent à 4, donc la priorité du thread enfant. devient également 4.

À proprement parler, la priorité par défaut du thread enfant est la même que celle du thread parent, et la priorité par défaut du thread principal Java est 5.

Il y a trois priorités définies en Java, à savoir la priorité la plus basse (1), la priorité normale (5) et la priorité la plus élevée (10). Le code est le suivant. La plage de priorités Java est [1, 10], la définition de la priorité d'autres nombres lèvera une exception IllegalArgumentException.

/**
 * The minimum priority that a thread can have.
 */
public final static int MIN_PRIORITY = 1;

/**
 * The default priority that is assigned to a thread.
 */
public final static int NORM_PRIORITY = 5;

/**
 * The maximum priority that a thread can have.
 */
public final static int MAX_PRIORITY = 10;

Ensuite, parlons du rôle de la priorité des threads. Examinons d'abord le code suivant. La logique du code consiste à créer 3 000 threads, qui sont : 1 000 threads avec priorité 1, 1 000 threads avec priorité 5 et 1 000 threads avec priorité 10. Utilisez minTimes pour enregistrer la somme des horodatages d'exécution de 1 000 threads MIN_PRIORITY, utilisez normTimes pour enregistrer la somme des horodatages d'exécution de 1 000 threads NORM_PRIORITY et utilisez maxTimes pour enregistrer la somme des horodatages d'exécution de 1 000 threads MAX_PRIORITY. En comptant la somme des horodatages en cours de chaque niveau de priorité, plus la valeur est petite, plus la priorité est élevée. Exécutons-le et voyons.

public class TestPriority {
    static AtomicLong minTimes = new AtomicLong(0);
    static AtomicLong normTimes = new AtomicLong(0);
    static AtomicLong maxTimes = new AtomicLong(0);

    public static void main(String[] args) {
        List<MyThread> minThreadList = new ArrayList<>();
        List<MyThread> normThreadList = new ArrayList<>();
        List<MyThread> maxThreadList = new ArrayList<>();

        int count = 1000;
        for (int i = 0; i < count; i++) {
            MyThread myThread = new MyThread("min----" + i);
            myThread.setPriority(Thread.MIN_PRIORITY);
            minThreadList.add(myThread);
        }
        for (int i = 0; i < count; i++) {
            MyThread myThread = new MyThread("norm---" + i);
            myThread.setPriority(Thread.NORM_PRIORITY);
            normThreadList.add(myThread);
        }
        for (int i = 0; i < count; i++) {
            MyThread myThread = new MyThread("max----" + i);
            myThread.setPriority(Thread.MAX_PRIORITY);
            maxThreadList.add(myThread);
        }

        for (int i = 0; i < count; i++) {
            maxThreadList.get(i).start();
            normThreadList.get(i).start();
            minThreadList.get(i).start();
        }

        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("maxPriority 统计:" + maxTimes.get());
        System.out.println("normPriority 统计:" + normTimes.get());
        System.out.println("minPriority 统计:" + minTimes.get());
        System.out.println("普通优先级与最高优先级相差时间:" + (normTimes.get() - maxTimes.get()) + "ms");
        System.out.println("最低优先级与普通优先级相差时间:" + (minTimes.get() - normTimes.get()) + "ms");

    }

    static class MyThread extends Thread {

        public MyThread(String name) {
            super(name);
        }

        @Override
        public void run() {
            System.out.println(this.getName() + " priority: " + this.getPriority());
            switch (this.getPriority()) {
                case Thread.MAX_PRIORITY :
                    maxTimes.getAndAdd(System.currentTimeMillis());
                    break;
                case Thread.NORM_PRIORITY :
                    normTimes.getAndAdd(System.currentTimeMillis());
                    break;
                case Thread.MIN_PRIORITY :
                    minTimes.getAndAdd(System.currentTimeMillis());
                    break;
                default:
                    break;
            }
        }
    }
}

Les résultats de l'exécution sont les suivants :

# 第一部分
max----0 priority: 10
norm---0 priority: 5
max----1 priority: 10
max----2 priority: 10
norm---2 priority: 5
min----4 priority: 1
.......
max----899 priority: 10
min----912 priority: 1
min----847 priority: 5
min----883 priority: 1

# 第二部分
maxPriority 统计:1568986695523243
normPriority 统计:1568986695526080
minPriority 统计:1568986695545414
普通优先级与最高优先级相差时间:2837ms
最低优先级与普通优先级相差时间:19334ms

Analysons les résultats ensemble. Regardons d'abord la première partie. Les threads exécutés au début ont une priorité élevée, une priorité normale et une priorité faible. Les threads exécutés à la fin ont également des priorités différentes. Cela montre que : les threads avec une priorité élevée ne signifient pas nécessairement une priorité plus élevée. que les threads avec une priorité plus élevée, les threads avec une priorité inférieure sont exécutés en premier. Vous pouvez également le dire autrement : l’ordre d’exécution du code n’a rien à voir avec la priorité du thread. En regardant les résultats de la deuxième partie, nous pouvons constater que la somme des horodatages d'exécution des 1000 threads avec la priorité la plus élevée est la plus petite, tandis que la somme des horodatages d'exécution des 1000 threads avec la priorité la plus basse est la plus grande. Par conséquent, nous pouvons savoir : un lot de threads à haute priorité sera exécuté en premier qu'un lot de threads à faible priorité, c'est-à-dire que les threads à haute priorité sont plus susceptibles d'obtenir des ressources CPU que les threads à faible priorité.

Y a-t-il vraiment 10 niveaux de thread dans chaque système d'exploitation ?

En tant que langage multiplateforme, Java dispose de 10 niveaux de threads, mais les valeurs de priorité des threads mappées aux différents systèmes d'exploitation sont différentes. Ensuite, je vais vous apprendre à vérifier la valeur du mappage de priorité des threads dans chaque système d'exploitation dans le code source OpenJDK.

En voyant le code source du Thread, définir la priorité du thread appelle finalement la méthode locale setPriority0();

private native void setPriority0(int newPriority);

Puis on retrouve la méthode JVM_SetThreadPriority correspondant à setPriority0() dans le code Thread.c de OpenJDK ;

static JNINativeMethod methods[] = {
    ...
    {"setPriority0",     "(I)V",       (void *)&JVM_SetThreadPriority},
    ...};

Nous trouvons le segment de code correspondant dans jvm.cpp basé sur JVM_SetThreadPriority;

JVM_ENTRY(void, JVM_SetThreadPriority(JNIEnv* env, jobject jthread, jint prio))
  JVMWrapper("JVM_SetThreadPriority");
  // Ensure that the C++ Thread and OSThread structures aren&#39;t freed before we operate
  MutexLocker ml(Threads_lock);
  oop java_thread = JNIHandles::resolve_non_null(jthread);
  java_lang_Thread::set_priority(java_thread, (ThreadPriority)prio);
  JavaThread* thr = java_lang_Thread::thread(java_thread);
  if (thr != NULL) {                  // Thread not yet started; priority pushed down when it is
    Thread::set_priority(thr, (ThreadPriority)prio);
  }
JVM_END

Sur la base du code de l'étape 3, nous pouvons constater que la clé est le code java_lang_Thread :: set_Priority() , continuez à chercher la méthode set_Priority() dans le code thread.cpp

void Thread::set_priority(Thread* thread, ThreadPriority priority) {
  trace("set priority", thread);
  debug_only(check_for_dangling_thread_pointer(thread);)
  // Can return an error!
  (void)os::set_priority(thread, priority);
}
 ;

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer