2013-03-08 16 views
7

Próbuję uruchomić następujący kod z punktów przerwa w następujący sposób:IntelliJ - nie zatrzymując się na wszystkich przerwań w kodzie wielowątkowym

new Thread(new Runnable() { 
     @Override 
     public void run() { 
      System.out.println("Starting"); //breakpoint here 
     } 
    }).start(); 

    int i = 10; 
    i++; //breakpoint here 

gdy ten kod działa tylko z I ++ przerwania jest trafiony ... Jeśli mogę usunąć ten, punkt przerwania drugiego wątku zostanie trafiony poprawnie. Dlaczego pojawia się to dziwne zachowanie?

Odpowiedz

6

Jest to udokumentowane w http://www.jetbrains.com/idea/webhelp/breakpoints-2.html:

Istnieją pewne przypadki, gdy IntelliJ IDEA nie zatrzyma się w punkcie wstrzymania. Rozważmy następującą sytuację: Dwa punkty przerwania są ustawiane różnymi metodami klasy, i tam zawieszenie polityki jest ustawione na Wszystkie. Po naciśnięciu jednego z punktów przerwania wykonywane są czynności krokowe. Jeśli w momencie przejścia kolejny wątek trafi w drugi punkt przerwania, IntelliJ IDEA nie zakończy się na tym.

Skopiowałem twój przykładowy kod i odtworzyłem sytuację. Oczywiście, jak mówi się w dokumentacji, po zatrzymaniu się w punkcie przerwania i++, jeśli uderzę w F8 (krok po kroku) program nie zatrzyma się na innym punkcie przerwania. Ale jeśli uderzę w F9 (wznowić), program zatrzyma się ponownie na innym punkcie przerwania.

+0

Osobiście uważam, że jest to stan wyścigu. W moim przypadku * wznowić * nadal nie ** nie ** wywołać punktu przerwania w nowym wątku. Jedynym sposobem naprawy jest to, aby nie zerwać tuż przed rozpoczęciem nowego wątku. To wszystko działa. – kervin

+0

Czy polityka zawieszania dla punktów przerwania jest ustawiona na "Wszystkie" (w przeciwieństwie do "Wątku")? –

+0

Tak, wszyscy są. Mogę wywołać ten problem, po prostu przesuwając punkt przerwania bliżej/dalej od początku wątku, więc sam potwierdza pewne warunki wyścigu. – kervin

0

Ponieważ drugi wątek to zaplanowany do uruchomienia w tle, a gdy program planujący wątek systemu operacyjnego podejmie decyzję o jego uruchomieniu, uruchomi się. Kiedy masz punkt przerwania, zostanie on trafiony.

Nie zacznie się koniecznie po prostu po uruchomieniu kodu, więc punkt przerwania pod numerem i++ zostanie trafiony natychmiast.

+0

Punkt przerwania NIGDY nie trafiony ...główny wątek kończy wykonywanie, widzę drukowany ciąg "Starting", więc linia została wykonana, ale nie nastąpiło przerwanie – Bober02

+0

@ Bober02 może twój debugger nie będzie debugowania wielowątkowego? –

0

Po prostu miałem ten problem i ze względu na innych, którzy do tego dochodzą, oto powód tego zachowania i sposób jego zmiany.

Jak zauważył Doron, istnieje dokumentacja dotycząca tego. Należy jednak zauważyć, że domyślnie wszystkie wątki w maszynie JVM są zawieszane po osiągnięciu punktu przerwania.

To, czego się spodziewasz (i czego się spodziewałem), to to, że zawieszony jest tylko wątek z punktem przerwania.

To nie jest to, czego chcesz, ani nie jest to, co chciałem.

Aby zmienić to zachowanie (i podać żądane zachowanie).

1) Utwórz punkt przerwania, klikając lewym przyciskiem na margines.
2) Naciśnij ctrl + shift + F8 (aby wywołać menu punktu przerwania).
3) Wybierz punkt przerwania. Zobaczysz opcje dla niego.
4) Upewnij się, że "Suspend" jest zaznaczone i wybrano opcję radiową "Thread".
5) Kliknij przycisk "Ustaw jako domyślny".

Teraz po uruchomieniu zobaczysz, że punkty przerwania w różnych wątkach są trafione.

Powiązane problemy