Prakhar Agrawal
Prakhar Agrawal

Reputation: 1032

How to run two threads at the same time in java

I am new to java and I am trying to learn about threads.

I am expecting an output of alternate hello this is thread one and hello this is thread two. but the output I get is as follows:

hello this is thread one
hello this is thread one
hello this is thread one
hello this is thread one
hello this is thread one
hello this is thread two
hello this is thread two
hello this is thread two
hello this is thread two
hello this is thread two

Below is my code. Can anyone please help me out to why I am getting this output as opposed to expected. And what is it that I can do to run the two threads in parallel.

public class ThreadDemo {
    public static void main(String args[]) {

        // This is the first block of code
        Thread thread = new Thread() {
            public void run() {
                for (int i = 0; i < 10; i += 2) {
                    System.out.println("hello this is thread one");
                }
            }
        };

        // This is the second block of code
        Thread threadTwo = new Thread() {
            public void run() {
                for (int i = 0; i < 10; i += 2) {
                    System.out.println("hello this is thread two");
                }
            }
        };

        // These two statements are in the main method and begin the two
        // threads.
        // This is the third block of code
        thread.start();

        // This is the fourth block of code
        threadTwo.start();
    }
}

Upvotes: 8

Views: 11548

Answers (7)

Avdhesh Yadav
Avdhesh Yadav

Reputation: 33

Below code is working...

public class ThreadDemo {

    public static void main(String args[]) throws InterruptedException {

        // This is the first block of code
        Thread thread = new Thread() {
            public void run() {
                for (int i = 0; i < 10; i += 2) {
                    System.out.println("hello this is thread one");
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException ex) {
                        Logger.getLogger(ThreadDemo.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
            }
        };

        // This is the second block of code
        Thread threadTwo = new Thread() {
            public void run() {
                for (int i = 0; i < 10; i += 2) {
                    System.out.println("hello this is thread two");
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException ex) {
                        Logger.getLogger(ThreadDemo.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
            }
        };

        // These two statements are in the main method and begin the two
        // threads.
        // This is the third block of code
        thread.start();

        // This is the fourth block of code
        threadTwo.start();

    }
}

Upvotes: 1

Martin Carpella
Martin Carpella

Reputation: 12603

Depending on the number of CPUs and/or CPU cores, multi-threading may only be simulated by your CPU by giving each thread a certain number of time before another thread is scheduled. See also Wikipedia on "Preemptive Multitasking"

Also, given today's CPUs and many cores and their speed, it may also be that the execution of the first thread already finished before the second one is started.

Also, both threads are battling for the lock in System.out, so they will lock each other out.

Let the threads run for longer times (higher number of iterations), and you will see the interleaving you are expecting.

Upvotes: 2

Andy Turner
Andy Turner

Reputation: 140544

If you want to have the threads' bodies wait until both threads are running, you can use something like a CountDownLatch, which can block until its internal counter counts down to zero:

final CountDownLatch latch = new CountDownLatch(2);
Thread thread = new Thread() {
  @Override public void run() {
    latch.countDown();
    latch.await();  // Execution waits here until latch reaches zero.

    // Rest of the method.
  }
}
Thread threadTwo = new Thread() {
  @Override public void run() {
    latch.countDown();
    latch.await();  // Execution waits here until latch reaches zero.

    // Rest of the method.
  }
}

thread.start();
threadTwo.start();

(Exception handling omitted for clarity)

This will guarantee that the "interesting bit" of the two threads' run methods will be executing at the same time. However, because of the unfair synchronization on the println() method you are calling, there is no guarantee of how the messages printed by the two threads will be interleaved:

  • Sometimes they might "perfectly" interleave (1, 2, 1, 2, ...)
  • Sometimes a few of one might be printed without anything from the other (1, 1, 2, 1, 2, 2, 2, ...)
  • Sometimes one might print all of its messages before the other (1, 1, 1, 1, 2, 2, 2, 2).

Upvotes: 1

Danyal Sandeelo
Danyal Sandeelo

Reputation: 12401

Your code would work too..add sleep in the first object.

   // This is the first block of code
        Thread thread = new Thread() {
            public void run() {
                for (int i = 0; i < 10; i += 2) {
                    System.out.println("hello this is thread one");
                    try {
                        sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }

        };

Upvotes: 1

NDizzle
NDizzle

Reputation: 24

Your code is working as expected, there is absolutely no guarantee that your implementation will execute in the pre-defined manner you are expecting.

I would suggest that you look at other methods of implementing multithreaded code such as join(), sleep() and finding one that better suits your needs.

Upvotes: 0

WalterM
WalterM

Reputation: 2706

The problem here is that PrintStream is synchronized which is not fair.

    final Lock lock = new ReentrantLock(true); //create fair lock
                        //after running this code change it to
                        //ReentrantLock(false); to see what happens

    // This is the first block of code
    Thread thread = new Thread() {
        public void run() {
            for (int i = 0; i < 10; i += 2) {
                lock.lock();
                System.out.println("hello this is thread one");
                lock.unlock();
            }
        }

    };

    // This is the second block of code
    Thread threadTwo = new Thread() {
        public void run() {
            for (int i = 0; i < 10; i += 2) {
                lock.lock();
                System.out.println("hello this is thread two");
                lock.unlock();
            }
        }

    };

    // These two statements are in the main method and begin the two
    // threads.
    // This is the third block of code
    thread.start();

    // This is the fourth block of code
    threadTwo.start();

when a lock is fair it will be alot slower, but when its not fair as in your first case it keeps grabbing the lock over and over before the other thread gets a chance to take it. A fair lock is like a queue. Whoever is queued to take it next gets it.

Upvotes: 3

cadrian
cadrian

Reputation: 7376

Just because threads may interlace does not mean that they will. Your threads simply run too fast. Try adding Thread.sleep() to make them run longer.

Upvotes: 3

Related Questions