Порядок выполнения потоков путем установки приоритета

1

Я установил приоритет потока в следующем порядке

A тогда B тогда C. Но когда я бегу ниже программы, иногда B запускается до A. Я не понимаю это выполнение, поскольку я устанавливаю приоритет B меньше, чем приоритет A.

public class AThread implements Runnable{
    public void run(){
    System.out.println("In thread A");
   }}

  public class BThread implements Runnable {
      public void run(){
    System.out.println("In thread B");  
    } 
   }

 public class CThread implements Runnable {

 public void run(){

    System.out.println("In thread C");

 }

}


 public class ThreadPriorityDemo {

   public static void main(String args[]){

    AThread A = new AThread();
    Thread tA = new Thread(A);


    BThread B = new BThread();
    Thread tB = new Thread(B);

    CThread C = new CThread();
    Thread tC = new Thread(C);

    tA.setPriority(Thread.MAX_PRIORITY);
    tC.setPriority(Thread.MIN_PRIORITY);
    tB.setPriority(tA.getPriority() -1);


    System.out.println("A started");
    tA.start();

    System.out.println("B started");
    tB.start();

    System.out.println("C started");
    tC.start();

}       

}

  • 0
    Вы можете опубликовать вывод, который вы получаете?
Теги:
multithreading

3 ответа

3
Лучший ответ

Приоритеты нитей, вероятно, не так, как вы думаете.

Приоритет потока - это рекомендация операционной системе, чтобы предпочесть один поток над другим в любой точке планирования или точке назначения распределения CPU, где задействованы эти два потока. Но как это реализовано, зависит от операционной системы и реализации JVM.

JavaMex хорошо обсуждает приоритеты потоков. Суть в том, что:

  1. Приоритеты могут не иметь никакого эффекта.
  2. Приоритеты - это только одна часть расчета, которое диктует планирование.
  3. Значимые значения приоритета Java могут быть переведены на одно и то же значение на практике (например, приоритеты 10 и 9 могут быть одинаковыми).
  4. Каждая ОС принимает собственные решения о том, что делать с приоритетами, поскольку Java использует базовый механизм потоковой обработки.

После этого обязательно прочтите следующую статью, в которой показано, как это делается в Linux и Windows.

Я думаю, что ваша проблема может возникнуть из третьего пункта выше (если вы работаете в Windows), но это может быть любая из других причин.

2

Я думаю, что правильный ответ: вы не можете надежно упорядочить запуск потока, установив приоритет потока.

Я думаю, что ваше замешательство проистекает из того факта, что документация заявляет

Нити с более высоким приоритетом выполняются вместо потоков с более низким приоритетом.

Хотя это верно, оно относится только к потокам, которые выполняют вычисления (или, в некоторых операционных системах, ждут общего ресурса). В таких случаях потоки с более высоким приоритетом получат больше процессорного времени, т.е. Будут выполняться в предпочтении тем, которые конкурируют за один и тот же ресурс.

Даже если приоритет потока повлияет на порядок запуска ваших потоков (скорее всего, это не так), все ваши потоки могут фактически выполняться параллельно на современных процессорах, поскольку они не влияют друг на друга.

Фактически порядок выполнения определяется каким-то другим фактором целиком: потоки не выполняют никаких соответствующих вычислений, они потратили большую часть своего (очень малого) времени выполнения, ожидающего общий ресурс, а именно System.out.

Нужно взглянуть на код, чтобы найти, что код, лежащий в основе System.out, который является PrintStream фактически выполняет атомарную синхронизацию:

public void write(byte buf[], int off, int len) {
    try {
        synchronized (this) {
            ensureOpen();
            out.write(buf, off, len);
            if (autoFlush)
                out.flush();
        }
    }
    catch (InterruptedIOException x) {
        Thread.currentThread().interrupt();
    }
    catch (IOException x) {
        trouble = true;
    }
}

Так что происходит, так это то, что первый поток, который достигает println() блокирует все остальные потоки, пока это не будет сделано с записью его вывода. Первый поток ветров, независимо от приоритета, потому что вы не можете прервать синхронизированный блок (что может привести к поражению цели монитора).

Какая нить получает блокировку сначала зависит от большего количества факторов, чем от приоритета потока и, возможно, даже от приоритета потока (Java) вообще.

1

Если вам нужно выполнить потоки с точным порядком, вы не можете сделать это с приоритетом потока. Вы можете использовать одну из поддерживающих синхронизацию. (например, замки, семафоры).

Ещё вопросы

Сообщество Overcoder
Наверх
Меню