[Java] Synchronizacja wątków

jakasnazwa89
Użytkownik
Użytkownik
Posty: 2
Rejestracja: 2 maja 2013, o 16:13
Płeć: Kobieta
Lokalizacja: tu
Podziękował: 1 raz

[Java] Synchronizacja wątków

Post autor: jakasnazwa89 »

1. Jaką wartość powinien zwracać przykładowy kod, a jaką zwraca? Dlaczego?
- Za każdym razem zwraca mi 30000 i takiej wartości sie spodziewałam. ( uruchomione 3 watki, każdy zwiększa licznik o 10000 )
2. Przetestuj rozwiązania z synchronizacją w metodzie run() i z synchronizacją w metodzie increment(). Które rozwiązanie jest lepsze?
- nie widze zadnej roznicy odkomentujac synchronizacje w tych metodach.

Dopiero sie ucze, dużo się już naczytałam o synchronizacji i wydaje mi sie ze rozumiem na czym polega ale z odpowiedzią na te pytania mam straszny problem. Będe bardzo wdzięczna za jakąkolwiek pomoc.

Kod: Zaznacz cały

public class WatkiSynch{
  public static void main(String args[]) throws InterruptedException{
    IncCounter cc = new IncCounter(0);
    Thread thread1 = new Thread(new IncrementCounterThread(cc));
    Thread thread2 = new Thread(new IncrementCounterThread(cc));
    Thread thread3 = new Thread(new IncrementCounterThread(cc));
    thread1.start();
    thread2.start();
    thread3.start();
    Thread.sleep(5000);
    System.out.println("Wartość licznika: " + cc.getCounter());
  }
}
 
class IncCounter{
  private int value;
  public IncCounter(int StartValue)
  {
    this.value = StartValue;
  }
  //public synchronized void increment()
  public void increment()
  {
    value++;
  }
  public int getCounter()
  {
    return value;
  }
}
 
class IncrementCounterThread implements Runnable{
  IncCounter counter;
  public IncrementCounterThread(IncCounter counter)
  {
    this.counter = counter;
  }
  public void run()
  {
    for(int i = 0; i < 10000; i++){
      //synchronized(counter){
          counter.increment();
      //}
    }
  }
}
Ostatnio zmieniony 2 maja 2013, o 16:25 przez Afish, łącznie zmieniany 1 raz.
Powód: Poprawa wiadomości.
Awatar użytkownika
kadiii
Użytkownik
Użytkownik
Posty: 642
Rejestracja: 20 gru 2005, o 21:04
Płeć: Mężczyzna
Lokalizacja: Wrocław
Pomógł: 130 razy

[Java] Synchronizacja wątków

Post autor: kadiii »

Nie wiem czy jesteś autorką powyższego kodu, ale wydaje się on trochę nieszczęśliwie dobrany. No, ale powalczmy.
Po pierwsze dodaj do swojego kodu dla przejrzystości nazwę każdego wątku:

Kod: Zaznacz cały

Thread thread1 = new Thread(new IncrementCounterThread(cc), "Pierwszy");
itd. dla każdego
następnie dopisz wyświetlanie nazwy na konsolę:

Kod: Zaznacz cały

	public void increment() {
		System.out.println(Thread.currentThread().getName());
		value++;
	}
Teraz widzimy już więcej. Potestuj parę razy i dopiero czytaj dalej. Spróbujmy odpowiedzieć na pytnanie pierwsze. Sumujemy jedną zmienną 3 wątkami - co może pójść nie tak? Pierwszy strzał - może kolejność wykonania wątków ma znaczenie? Ale chwila co to za różnica czy pierwszy wątek doda pod rząd 1 do wartości a potem kolejny wątek zrobi to samo. Trochę się pomieszają, ale w sumie będziemy mieć 30000 inkrementacji czyli wynik 30000. Proste! ...
Ale chwila. Czy operacja inkrementacji jest atomowa? Chwila zastanowienia i tak - inkrementacja to getValue() następnie dodawanie i dalej przypisanie. Czy może tu być problem? A co jeśli jeden wątek odczyta wartość, drugi zaraz po nim? Jaki będzie finalny wynik. Ciężkie do uzyskania bo mamy szybkie maszyny, ale jak już się pojawi to znalezienie takiego błędu to istny horror. Lećmy dalej.
Zadanie drugie pyta nas o dwie metody synchronizacji : synchronizacja na metodzie i synchronizacja na obiekcie(monitorem). Dodaj wspomniane synchronizacje i sprawdź co się stanie. Czy jest jakaś różnica a jeśli tak/nie to dlaczego? Teraz zmień zakres wyrażenia synchronizującego aby obejmował całą pętlę:

Kod: Zaznacz cały

	public void run() {
		synchronized (counter) {
			for (int i = 0; i < 100; i++) {
				counter.increment();
			}
		}

	}
Co teraz się zmieniło i dlaczego? Zastanów się również w jakiej sytuacji zależy nam na danym sposobie blokowania. Pamiętaj, że celem programowania wielowątkowego jest wykonywanie zadań "równolegle" - dzięki temu programy wykorzystują potencjał procesora i działają szybciej. Pobaw się trochę tym zadaniem - dodaj kolejną metodę, zadbaj o jej synchronizację, może spróbujesz uzyskać deadlock-a. Mam nadzieję, że po przeczytaniu i poświęceniu chwili czasu sytuacja z wątkami się wyjaśni.
jakasnazwa89
Użytkownik
Użytkownik
Posty: 2
Rejestracja: 2 maja 2013, o 16:13
Płeć: Kobieta
Lokalizacja: tu
Podziękował: 1 raz

[Java] Synchronizacja wątków

Post autor: jakasnazwa89 »

Dziękuję chyba już mi się wszystko wyjaśniło
ODPOWIEDZ