2010-08-31 4 views
9

Я новичок в Java, и я посещаю курс параллельного программирования. Я отчаянно пытаюсь получить минимальный рабочий пример, который может помочь продемонстрировать концепции, которые я узнал, используя «синхронизированное» ключевое слово и совместное использование объекта по потокам. Искали, но не смогли получить базовую структуру. Java-программисты, любезная помощь.Совместное использование объекта между двумя потоками и основной программой

ответ

4

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

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]); 
} 

Но, если вы синхронизировать arr вокруг цикла вы всегда будете видеть все 0 с в распечатке. Если вы раскомментируете синхронизированный блок, код будет работать без ошибок.

+2

Вы также можете избавиться от ошибок, синхронизируя на 'arr' только строки инкремента и декремента: http://pastebin.com/vN4E527P. Это подчеркивает тот факт, что единственными небезопасными частями являются эти две строки. –

+0

Иногда я получаю строку случайных чисел. Я озадачен. Можете ли вы любезно объяснить работу? – devnull

+0

Не должно быть arr [i% arr.length] - и arr [i% arr.length] ++ балансировать, поскольку он выполняется столько же раз? Другими словами, не должен ли результат всегда равен нулю? – devnull

7

Простой пример. Надеюсь, вам понравится футбол (или футбол). :)

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

Как это показывает состояние гонки? – jjnguy

+0

Создайте еще несколько объектов Игрока, чтобы сделать их более очевидными. – Mike

+0

Насколько я вижу, он будет чередовать имена игроков. Но, не обязательно, каждый другой, потому что именно так работает переключение контекста. – jjnguy

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