I'm trying to understand how to implement Threads disputing global variables. In my implementation I created 2 variables and I want 4 Threds (e.g.) to dispute it by decrementing.
The first problem is that the way I implemented to consume will always follow an order (first Thread decrements the flake ice cream and the second Thread decrements the chocolate ice cream).
Is there any way to improve this rule?
And I wouldn't want to know what would be the best place to use CountDownLatch
public class IceCream implements Runnable {
private static int flake = 1;
private static int chocolate = 1;
@Override
public void run() {
buyIceCream();
}
private void synchronized buyIceCream() {
try {
if(IceCream.flake>0) {
System.out.println("");
System.out.println("successfully purchased " +Thread.currentThread().getName());
Thread.sleep(200);
IceCream.flake--;
System.out.println("");
}
else if(IceCream.chocolate>0) {
System.out.println("");
System.out.println("successfully purchased " +Thread.currentThread().getName());
Thread.sleep(200);
IceCream.chocolate--;
System.out.println("");
}
else {
System.out.println("No more ice cream " +Thread.currentThread().getName());
}
}
catch(Exception e) {
}
}
}
public static void main(String[] args) throws InterruptedException {
IceCream c = new IceCream();
Thread[] t = new Thread[4];
for(int i = 0; i<t.length; i++) {
t[i] = new Thread(c);
t[i].setName("Kid"+ i);
t[i].start();
t[i].join();
}
}
This is a mistake:
The
join()call does not return until the thread has ended, so your program will never allow more than one thread to run at the same time. You can fix the mistake by writing two separate loops. The first one creates and starts all of the threads, and then the second one joins all of them.This is another mistake:
Wrapping everything that a thread does inside a single
synchronizedmethod is another way to ensure that no two of your threads will be allowed to run at the same time.At the very least, you should remove the
sleep()calls from thesynchronizedblock:I also moved the
System.out.println()call out of thesynchronizedblock because I know that the characters printed by any single call will not be interleaved with characters printed by a single call from a different thread. (See https://stackoverflow.com/a/9459743/801894)