Thread without sleep

I’m pretty new using Threads and I just did a little program to understand how it works. As a example a did a prime numbers exercise, the program is running perfectly but what I have discovered is that if I don’t use sleep(), the order of the numbers change everytime I press run (without changing the code). So why is happening that?

    class Prime extends ThreadDemo implements Runnable 
    {
    public void run()
    {
        for(int i=2;i<=20;i++)
        {
            if(prime(i))
            {
                System.out.printf ("Prime No.= %d n",i);
            }
        }
    }
    }

    class notPrime extends ThreadDemo implements Runnable
    {
       int number= 0;
       public void run()
       {
           prime(number);
       }
    }

class ThreadDemo
{
    public boolean prime(int start_value)
    {
        for(int i=2; i<start_value; i++)
        {
           if(start_value%i == 0)
           {
               System.err.printf ("No. Prime = %d n", start_value);
               return false;
           }
        }
        return true;
    }


    public static void main(String args[])
    {
        Prime th1 = new Prime();
        Thread childOne = new Thread(th1);
        childOne.start();
        notPrime th2 = new notPrime();
        Thread childTwo = new Thread(th2);
        childTwo.start();   
    }
}

This is the result after I pressed run:

This is the result after I pressed run

This is the result after pressing again run:

This is the result after pressing again run

Answer

There are two reasons why this happens :

  1. Your prime method is not synchronized.
  2. Even if you synchronize the prime method, you are passing different instances of ThreadDemo to your threads. Locks are obtained on objects. If two threads are passed two different objects of ThreadDemo, each thread will lock its own instance of ThreadDemo thus allowing the Threads to run in parallel.

There are a couple of changes you need to make to your code to make sure that the same ThreadDemo is used for both your threads.

class NotPrimeRunnable implements Runnable {
    private ThreadDemo threadDemo;
    int number = 0;

    public NotPrimeRunnable(ThreadDemo threadDemo) {
        this.threadDemo = threadDemo;
    }

    public void run() {
        threadDemo.prime(number);
    }
}

class PrimeRunnable implements Runnable {

    private ThreadDemo threadDemo;

    public PrimeRunnable(ThreadDemo threadDemo) {
        this.threadDemo = threadDemo;
    }

    @Override
    public void run() {
        for (int i = 2; i <= 20; i++) {
            if (threadDemo.prime(i)) {
                System.out.printf("Prime No.= %d n", i);
            }
        }
    }

}

class ThreadDemo {
    public synchronized boolean prime(int start_value) {
        for (int i = 2; i < start_value; i++) {
            if (start_value % i == 0) {
                System.err.printf("No. Prime = %d n", start_value);
                return false;
            }
        }
        return true;
    }

    public static void main(String args[]) {
        ThreadDemo runnableTask = new ThreadDemo();
        PrimeRunnable th1 = new PrimeRunnable(runnableTask);
        Thread childOne = new Thread(th1);
        childOne.start();
        NotPrimeRunnable th2 = new NotPrimeRunnable(runnableTask);
        Thread childTwo = new Thread(th2);
        childTwo.start();
    }
}

This will fix your problem.

Leave a Reply

Your email address will not be published. Required fields are marked *