Hey everyone~! I am pretty new to threading but I'm trying to figure it out by playing around with its possibilities. I wrote a program where 2 threads are supposed to "race" to count to 10 and then the first one there says "I win!" and the second says "I lose...". However, I am having issues as both say "I win!" How do I fix this??? I keep playing around with it but I can't get it to work.

public class BetaClass implements Runnable
{
    private String name;
    private int counter = 1;
    private static volatile boolean alreadyWon = false;
    private Thread executor;
    public BetaClass(String name)
    {
        this.name = name;
        executor = new Thread(this);
        executor.setDaemon(true);
        executor.start();
    }
    public void run()
    {
        while (counter<10)
        {
            System.out.println(name+": "+counter);
            try
            {
                executor.sleep(500);
            }
            catch (InterruptedException ie) {}
            finally{counter++;}
        }
        run2();
    }
    
    public synchronized void run2()
    {
        if (!alreadyWon)
        {
            System.out.println(name+": I win~!");
            alreadyWon = true;
        }
        else
            System.out.println(name+": I lose...");
    }
    
    public static void main(String[] args)
    {
        BetaClass alpha = new BetaClass("Alpha");
        BetaClass beta = new BetaClass("Beta");
    }
}

Recommended Answers

All 2 Replies

Bump...

I need someone to help me with this. Also, can someone give a good explanation and sample code with keyword volatile? I understand synchronized methods, but I don't understand when to make variables volatile... Can you post a sample code and explain the outputs in the scenarios in which the variable is and isn't declared volatile? thanks so much!

>I don't understand when to make variables volatile.

Declaring a volatile Java variable means: The value of this variable will never be cached thread-locally: all reads and writes will go straight to "main memory". Access to the variable acts as though it is enclosed in a synchronized block, synchronized on itself.

Have a look at this discussion - When to use volatile?

Sample,

public class BetaClass implements Runnable
{
    private String name;
    private int counter = 1;
    private static volatile boolean alreadyWon = false;
    private Thread executor;
    public BetaClass(String name)
    {
        this.name = name;
        executor = new Thread(this);
        executor.setDaemon(true);
        executor.start();
    }
    public void run()
    {
        while (counter<10)
        {
            System.out.println(name+": "+counter);
            try
            {
                executor.sleep(500);
            }
            catch (InterruptedException ie) {}
            finally{counter++;}
        }
        run2(this);
    }
  //static synchronized - Lock is obtained on the corresponding class object.  
  public static synchronized void run2(BetaClass obj)
    {
        if (!BetaClass.alreadyWon)
        {
            System.out.println(obj.name+": I win~!");
            BetaClass.alreadyWon = true;
        }
        else
            System.out.println(obj.name+": I lose...");
    }
    
    public static void main(String[] args)
    {
        BetaClass alpha = new BetaClass("Alpha");
        BetaClass beta = new BetaClass("Beta");
        
  // Deamon threads are then all automatically stopped when the JVM shuts down. 
        try {
            Thread.currentThread().sleep(8000);
        }catch(Exception ex) {}
    }
}
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.