Je suis nouveau à Java et j'assiste à un cours de programmation simultanée. J'essaie désespérément d'obtenir un exemple de travail minimal qui peut aider à démontrer les concepts que j'ai appris à utiliser le mot-clé 'synchronized' et à partager un objet entre les threads. A cherché, mais n'a pas pu obtenir un cadre de base. Les programmeurs Java, veuillez aider.Partage d'un objet entre deux threads et le programme principal
Répondre
Voici un exemple très abouti de partage d'un tableau entre deux threads. Habituellement, vous verrez tous les zéros, mais parfois les choses deviennent vives et vous voyez d'autres nombres.
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]);
}
Mais, si vous synchronisez sur arr
autour de la boucle, vous verrez toujours tous les 0
s dans l'impression. Si vous décommentez le bloc synchronisé, le code s'exécutera sans erreur.
Un exemple simple. J'espère que vous aimez le football (ou le football). :)
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;
}
}
Comment cela montre-t-il une condition de concurrence? – jjnguy
Instancie un peu plus d'objets Player pour le rendre plus évident. – Mike
Autant que je peux voir, il alternera entre les noms de joueurs. Mais, pas nécessairement tous les autres, parce que c'est juste comment le changement de contexte fonctionne. – jjnguy
Vous pouvez également vous débarrasser des erreurs en synchronisant sur 'arr' pour seulement les lignes d'incrémentation et de décrémentation: http://pastebin.com/vN4E527P Ceci souligne le fait que les seules parties non-thread-safe sont ces deux lignes. –
Parfois, je reçois une chaîne de nombres aléatoires. Je suis perplexe. Pouvez-vous expliquer le fonctionnement? – devnull
Ne devrait pas arr [i% arr.length] - et arr [i% arr.length] ++ s'équilibrer car il est exécuté le même nombre de fois? En d'autres termes, le résultat ne devrait-il pas toujours être zéro? – devnull