2010-08-31 15 views
9

Jestem nowicjuszem w Javie i uczęszczam na kurs programowania współbieżnego. Rozpaczliwie staram się uzyskać minimalny przykład pracy, który może pomóc w zademonstrowaniu pojęć, których się nauczyłem, takich jak używanie słowa kluczowego "zsynchronizowanego" i dzielenie obiektu przez wątki. Szukałem, ale nie mogłem uzyskać podstawowej struktury. Programiści Java, proszę o pomoc.Udostępnianie obiektu między dwoma wątkami i głównym programem

Odpowiedz

4

Oto przykład bardzo udanego udostępnienia tablicy między dwoma wątkami. Zwykle zobaczysz wszystkie zera, ale czasami rzeczy stają się paskudne i widzisz inne liczby.

final int[] arr = new int[100]; 
Thread one = new Thread() { 
    public void run() { 
     // synchronized (arr) { 
      for (int i = 0; i < arr.length * 100000; i++) { 
       arr[i % arr.length]--; 
      } 
     // } 
    } 
}; 
Thread two = new Thread() { 
    public void run() { 
     // synchronized (arr) { 
      for (int i = 0; i < arr.length * 100000; i++) { 
       arr[i % arr.length]++; 
      } 
     //} 
    } 
}; 
one.start(); 
two.start(); 
one.join(); 
two.join(); 
for (int i = 0; i < arr.length; i++) { 
    System.out.println(arr[i]); 
} 

Ale jeśli synchronizacja na arr wokół pętli będziesz zawsze zobaczyć wszystkie 0 S w wydruku. Jeśli odkomentujesz zsynchronizowany blok, kod będzie działał bez błędu.

+2

Możesz także pozbyć się błędów, synchronizując w 'arr' tylko linie przyrostu i dekrementacji: http://pastebin.com/vN4E527P Podkreśla to fakt, że jedynymi niebezpiecznymi dla gwintów częściami są te dwie linie. –

+0

Czasami otrzymuję ciąg liczb losowych. Jestem zdziwiony. Czy możesz wyjaśnić pracę? – devnull

+0

Nie powinien arr [i% arr.length] - i arr [i% arr.length] ++ wyrównać, ponieważ jest wykonywany tyle samo razy? Innymi słowy, czy wynik nie powinien być zawsze zerowy? – devnull

7

Prosty przykład. Mam nadzieję, że lubisz piłkę nożną (lub piłkę nożną). :)

public class Game { 

public static void main(String[] args) { 
    Ball gameBall = new Ball(); 
    Runnable playerOne = new Player("Pasha", gameBall); 
    Runnable playerTwo = new Player("Maxi", gameBall); 

    new Thread(playerOne).start(); 
    new Thread(playerTwo).start(); 
} 

} 

public class Player implements Runnable { 

private final String name; 
private final Ball ball; 

public Player(String aName, Ball aBall) { 
    name = aName; 
    ball = aBall; 
} 

@Override 
public void run() { 
    while(true) { 
    ball.kick(name); 
    } 
} 

} 

public class Ball { 

private String log; 

public Ball() { 
    log = ""; 
} 

//Removing the synchronized keyword will cause a race condition. 
public synchronized void kick(String aPlayerName) { 
    log += aPlayerName + " "; 
} 

public String getLog() { 
    return log; 
} 

} 
+1

Jak to pokazuje stan wyścigu? – jjnguy

+0

Wywołaj jeszcze kilka obiektów odtwarzacza, aby były bardziej oczywiste. – Mike

+0

O ile widzę, będzie on przełączał się między nazwami graczy. Ale niekoniecznie co drugi, ponieważ tak właśnie działa przełączanie kontekstów. – jjnguy

Powiązane problemy