I am new to Java and I'm attending a Concurrent Programming course. I am desperately trying to get a minimal working example that can help to demonstrate concepts I have learnt like using 'synchronized' keyword and sharing an object across threads. Have been searching, but could not get a basic framework. Java programmers, kindly help.
views:
121answers:
2
+5
A:
A simple example. Hope you like soccer (or 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;
}
}
Mike
2010-08-31 01:42:26
How does this show a race condition?
jjnguy
2010-08-31 02:05:29
Instantiate a few more Player objects to make it more obvious.
Mike
2010-08-31 02:07:56
As far as I can see, it will alternate between player names. But, not necessarily every other, because that's just how context switching works.
jjnguy
2010-08-31 02:09:23
Instantiate a few more, remove the synchronized keyword. ThreadA moves into call System.out.println(). ThreadB does so shortly after. Blammo.
Mike
2010-08-31 02:10:43
@Mike, Ok, I will try it myself before I criticize.
jjnguy
2010-08-31 02:12:56
It's okay. Double check me. :)
Mike
2010-08-31 02:13:40
@Mike: Isn't `System.out.println` synchronized?
Daniel Trebbien
2010-08-31 02:15:25
Google says yes. Learn something new every day. I'll modify my example. Thanks. :)
Mike
2010-08-31 02:18:01
Hmmm, I guess I don't see it...
jjnguy
2010-08-31 02:21:01
@Mike: You could append the strings to an `ArrayList<String>`. That's what I was thinking originally as a good example (i.e., two threads calling a thread-unsafe method on the same object without proper synchronization).
Daniel Trebbien
2010-08-31 02:21:49
@Dan, what did you think of my example?
jjnguy
2010-08-31 02:23:52
@Justin: I think that that works, the reason being that the `--` and `++` operations are not atomic. It might take many runs of this program to see the problem, however, because both threads would have to iterate from 0 to 400,000 in lock step. One note: Instead of having the current thread sleep, you could join the current thread on both of the threads that you started.
Daniel Trebbien
2010-08-31 02:31:11
@Dan, with running 4000 times through, you do see a little bit of error in the results.
jjnguy
2010-08-31 02:35:00
@Justin: Wow! I didn't expect it, but there were *a lot* of errors the first time that I ran it. Interesting.
Daniel Trebbien
2010-08-31 02:50:35
+2
A:
Here is a very shot example of sharing an array between two threads. Usually you will see all zeros, but sometimes things get screwy and you see other numbers.
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]);
}
But, if you synchronize on arr
around the looping you will always see all 0
s in the print out. If you uncomment the synchronized block, the code will run without error.
jjnguy
2010-08-31 01:47:09
You can also get rid of the errors by synchronizing on `arr` for just the increment and decrement lines: http://pastebin.com/vN4E527P This underscores the fact that the only thread-unsafe parts are those two lines.
Daniel Trebbien
2010-08-31 03:00:25
Sometimes I am getting a string of random numbers. I am puzzled. Can u kindly explain the working?
iJeeves
2010-08-31 03:30:01
Shouldn't arr[i % arr.length]-- and arr[i % arr.length]++ balance out as it is being executed the same number of times? In other words shouldn't the result be zero always?
iJeeves
2010-08-31 03:31:58
@n0vi Yea, that is exactly why this is a great example of problems caused by sharing objects over multiple threads. What happens is the two threads try to increment and decrement the same item in the array at the same time, and one overwrites the other, so you don't see all `0` like you should.
jjnguy
2010-08-31 12:23:47