Wątki w Jave poziom Hard

0

Witam

Przeglądam sobie testy z SCJP i znalazłem ciekawe zadanie z wątków. Jednak nie do końca wiem co się dzieje.

Oto kod:

public class Cruiser {
    private int a = 0;
    
    public void foo() {
        Runnable r = new LittleCruiser();
        new Thread(r).start();
        new Thread(r).start();
    }
    
    public static void main(String arg[]) {
        Cruiser c = new Cruiser();
        c.foo();
    }
    
    public class LittleCruiser implements Runnable {
        public void run() {
            int current = 0;
            for (int i = 0; i < 4; i++) {
                current = a;
                System.out.print(current + ", ");
                a = current + 2;
            }
        }
    }
}

Oczywiście pytanie do kodu: Jaki będzie możliwy output?

A) 0, 2, 4, 0, 2, 4, 6, 6,
B) 0, 2, 4, 6, 8, 10, 12, 14,
C) 0, 2, 4, 6, 8, 10, 2, 4,
D) 0, 0, 2, 2, 4, 4, 6, 6, 8, 8, 10, 10, 12, 12, 14, 14,
E) 0, 2, 4, 6, 8, 10, 12, 14, 0, 2, 4, 6, 8, 10, 12, 14,

B - jest dla mnie oczywistością,

Jednak poprawną odpowiedzią jest również A.

Po kompilacji kodu i odpaleniu mam taki output: 0, 2, 4, 6, 0, 2, 4, 6,

Dodam że mam dwurdzeniowy procek.

Nie wiem skąd się biorą podwójne wartości wypisywane na ekran (np podówjne 0).

Przecież wątki korzystają z wartości tego samego pola a.

Proszę o jakieś sensowne i łopatologiczne wytłumaczenie.

Dzięki wielkie DD:D

0

Możliwy scenariusz do twojego przypadku:
Jeden wątek zatrzymuje się w pierwszej iteracji na instrukcji current = a, podczas gdy zmienna a ma wartość 0. Potem drugi wątek się wykonuje do końca (wypisując 0, 2, 4, 6, a potem wraca pierwszy wątek i wypisuje to samo (zmienna a jest nadpisywana wartością 2 w linijce a = current + 2, a potem leci tak samo jak w pierwszym).

Możliwy scenariusz do przypadku A:
Prawie to samo, tylko w ostatniej iteracji wątku 2 ten wątek jest zapauzowany (przed wypisaniem 6), potem wątek pierwszy wypisuje liczby, a na koniec sterowanie wraca do wątku 2 i wypisywane jest 6.

0

Przecież wątki korzystają z wartości tego samego pola a.

Ale w dwóch różnych instancjach klasy Cruiser. Więc jednak z dwóch pól.

0

Dzięki za posty:)

0

Też mam dwurdzeniowy procesor, przy każdym uruchomieniu programu (niezależnie od priorytetów wątków) mam wyjście 0,0,2,2,4,4,6,6. By lepiej zrozumieć jak to działa (kiedy jest przełączenie wątków) warto trochę rozbudować kod.

public class Cruiser {
    private int a = 0;
 
    public void foo() {
        Runnable r = new LittleCruiser();
        new Thread(r,"w1").start();
        new Thread(r,"w2").start();
    }

    public static void main(String arg[]) {
        Cruiser c = new Cruiser();
        c.foo();
    }

    public class LittleCruiser implements Runnable {
        public void run() {
            int current = 0;
            for (int i = 0; i < 4; i++) {
                current = a;
                System.out.print((a++) +Thread.currentThread().getName()+"a ");
                System.out.print(current +Thread.currentThread().getName()+"c ");
                a = current + 2;
            }
        }
    }
}

1 użytkowników online, w tym zalogowanych: 0, gości: 1