не должен ли основной поток начинать выполнение, когда другие потоки переводятся в спящий режим

#java #thread-sleep

#java #поток-sleep

Вопрос:

На мой взгляд, вывод этой программы может быть только

 Hello 0 1 2 3 4 Yes
  

Но в списке ответов

 0 1 2 3 4 Hello Yes
  

также в качестве возможного ответа. Мой вопрос в том, когда тест переводится в спящий режим, не должен ли main, являющийся единственным другим потоком, переходить в состояние running, таким образом, Hello всегда должен печататься первым?

 public class Lean   
{
    public static void main(String args[]) throws Exception 
    {
        Test test = new Test();
        test.start();
        System.out.print("Hello ");
        test.join();
        System.out.print("Yes");
    }
}

class Test extends Thread
{
    public void run()
    {
        try
        {
            Thread.sleep(2000);
        } catch (InterruptedException e)
        {}
        for (int counter=0; counter<5 ; counter  )
        {
            System.out.print(counter   " ");
            }
    }
}
  

Комментарии:

1. Порядок выполнения потоков не является детерминированным … может случиться так, что спящий режим позволит запустить другой процесс, и ваш тестовый поток — это тот, который возобновляется, когда выполнение возвращается к вашему процессу… спящий режим не является хорошим методом синхронизации.

2. @forsvarir: Вы должны опубликовать это в качестве ответа.

Ответ №1:

Порядок выполнения потоков не является детерминированным … может случиться так, что спящий режим позволит запустить другой процесс, и ваш тестовый поток — это тот, который возобновляется, когда выполнение возвращается к вашему процессу… спящий режим не является хорошим методом синхронизации

Если вы действительно хотите начать контролировать порядок выполнения операций, тогда вам нужно посмотреть на такие вещи, как Мьютекс…

Комментарии:

1. Спасибо за ответы. Я хочу знать, всегда ли один поток будет выполняться в данный момент времени. Если есть только два потока, как в программе выше (тестовый и основной), то если один из них находится в спящем режиме и не блокирует другой поток, удерживая какую-либо блокировку и т.д., То не должен ли основной поток включиться? Возможно ли, чтобы все потоки находились в состоянии runnable и в этот момент не выполнялся ни один поток, что, похоже, имеет место здесь.

2. @Varun: Поскольку вы не управляете планировщиком, все потоки для вашего приложения могут находиться в работоспособном состоянии, но ОС может отдавать все время выполнения другим процессам. Когда он возвращается к вашему процессу, он может возобновить любой из ваших потоков в работоспособном состоянии. На большинстве платформ довольно маловероятно, что двухсекундный спящий режим не приведет к тому, что основной поток немного остановится, однако нет никакой гарантии. Помните, что java работает на множестве различных аппаратных средств / операционных систем, поэтому процесс с приоритетом REAL_TIME может использовать все циклы, если запускается аппаратное событие…

3. Спасибо за объяснение. Я не принял во внимание роль операционной системы и то, что это может отвлекать процессорное время на процессы, не связанные с моей программой Java. Еще раз спасибо.

Ответ №2:

Большую часть времени он будет делать то, что вы ожидаете. Но есть действительно крошечный шанс, что даже если поток перейдет в спящий режим на 2 секунды, main не получит шанса на запуск.

Суть в том, что Thread.sleep не будет заставлять планировщик запускать другой поток (хотя это даст ему довольно хорошую подсказку).