Home > Back-end >  Start Threads same time and dispute global variables
Start Threads same time and dispute global variables

Time:03-19

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

CodePudding user response:

This is a mistake:

t[i].start();
t[i].join();

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.

for(int i = 0; i<t.length; i  ) {
    t[i] = new Thread(c);
    t[i].setName("Kid"  i);
    t[i].start();
}
for(int i = 0; i<t.length; i  ) {
    t[i].join();    
}

This is another mistake:

public void run() {
    buyIceCream();
}   
    
private void synchronized buyIceCream() {
    ...
}

Wrapping everything that a thread does inside a single synchronized method 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 the synchronized block:

private void buyIceCream() {
    boolean success = false;
    synchronized (this) {
        if(IceCream.flake>0) {
            IceCream.flake--;
            success = true;
        }
        else if(IceCream.chocolate>0) {
            IceCream.chocolate--;
            success = true;
        }
    }
    if (success) {
        synchronized(this) {
            System.out.println("");
            System.out.println("successfully purchased "  Thread.currentThread().getName());
            System.out.println("");
        }
    }
    else {
        synchronized(this) {
            System.out.println("No more ice cream "  Thread.currentThread().getName());
        }
    }
    try {
        Thread.sleep(200);
    }
    catch(Exception e) {
        System.out.println("Never, EVER, completely ignore an exception.");
    }       
}
  • Related