2009-10-31 3 views
0
public class Test extends Thread{ 
    public void hello(String s){ 
     System.out.println(s); 
    } 
    public void run(){ 
     hello("I’mrunning..."); 
    }//endofrun() 
    public static void main(String [] args){ 
     Test t=new Test(); 
    System.out.println("always first"); 
     t.start(); 

     System.out.println("always second but why?"); 
    } 
} 

Я запустил этот кусок кода 30 раз.Обработка ошибок в java

Почему «всегда второе, но почему?» всегда второй на консоли? Когда вызывается t.start(), у нас есть 2 потока. (2 стопки): основная нить и вторая нить. поэтому «i'am running» должен быть иногда вторым выходом на консоли. Когда я удаляю вывод «всегда первый», чем два выхода слева, ведем себя недетерминированным (так оно и должно быть)

так что не так в моих мыслях, почему System.out.println («всегда первый «); влияя на параллелизм?

ответ

5

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

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

Если вы хотите обеспечить определенный заказ, вам нужно сделать это явно - если вы не возражаете, в каком порядке происходят события, то нет проблем :)

+0

Конечно, детерминированное поведение затрудняет тестирование. –

-2

System.out.println("always first") всегда будет первым, потому что он приходит до начинается вторая нить, поэтому он не будет влиять на параллелизм.

попытка размещения «всегда первый» предложение послеt.start();, вы можете получить то, что вы ожидали :)

1

Я запустить этот кусок кода в 30 раз.

Запустите его еще семь миллиардов раз на каждую ОС и возможную аппаратную комбинацию и сообщите о своих результатах. 30 - очень низкое значение навсегда.

Почему «всегда второй, но почему?» всегда второй на консоли?

Сколько у вас ядер? Большинство планировщиков потоков будут поддерживать текущий текущий поток поверх вновь созданного, особенно на отдельных ядрах, и будет способствовать синхронизации потоков между ядрами как можно ближе к точке (объект потока и System.out должны быть переданы между потоками ОС).

Данная резьба не детерминирована, и большинство ОС не гарантирует справедливость и своевременность, это никак не ошибка, с которой она ведет себя таким образом.

Если вы хотите явное упорядочение между потоками, то вы должны использовать либо синхронизированные блоки, либо более мощные классы в java.util.concurrent. Если вы хотите не детерминированное поведение, но чтобы запустить другой поток, вы можете дать подсказку планировщику, используя Thread.yield().

public static void main (String [] args) 
{ 
    FirstThreadBug t = new FirstThreadBug(); 
    System.out.println ("always first"); 
    t.start(); 
    yield(); 
    System.out.println ("always second but why?"); 
} 
0

Почему «всегда второй, но почему?"Всегда второй на консоли?

Это не всегда второй. Мне удалось произвести как упорядоченности примерно 5 выполнений кода. Оба упорядоченности действительны, и планирование потоков зависит от операционной системы, и, возможно, JVM и аппаратное обеспечение ., а также

так, что не так в моем мышлении, почему System.out.println («всегда первый»);? влияющий на параллелизм

Ваше мышление правильно, ваши эксперименты в заблуждение вы;)

Смежные вопросы