Abhiroop Nandi Ray
Abhiroop Nandi Ray

Reputation: 397

Printing numbers in loop with two threads

I am trying out codes with multiple threads. Below is my code:

package com.thread.practice;

public class ThreadPratice1 {

    public static void main(String[] args) {
        MyRunnable r = new MyRunnable();
        Thread t1 = new Thread(r, "Thread 1");
        Thread t2 = new Thread(r, "Thread 2");
        t1.start();
        t2.start();
    }
}

package com.thread.practice;

public class MyRunnable implements Runnable {
    private static int i = 0;
    @Override
    public void run() {
        for(i = 0; i <10;i++){
            System.out.println("Thread: "+ Thread.currentThread().getName()
                    +" value of i: "+i);
            try {
                //System.out.println("Thread: "+ i);
                Thread.sleep(1000);
                //System.out.println("inside runnable: "+Thread.currentThread().getState());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

But in the output it is always printing the value of i as 0 twice in the beginning.

Output is coming kind of like this:

Thread: Thread 1 value of i: 0
Thread: Thread 2 value of i: 0
Thread: Thread 1 value of i: 2
Thread: Thread 2 value of i: 2
Thread: Thread 1 value of i: 3
Thread: Thread 2 value of i: 4
Thread: Thread 1 value of i: 5
Thread: Thread 2 value of i: 6
Thread: Thread 1 value of i: 7
Thread: Thread 2 value of i: 8
Thread: Thread 1 value of i: 9

May someone please help me in understanding this issue?

Upvotes: 0

Views: 746

Answers (4)

chengpohi
chengpohi

Reputation: 14217

First, You shouldn't use the primitive int type for concurrency, it's not thread safe and it maybe will cause Race Condition,

and try to use AtomicInteger to replace int, it's thread safe. the example maybe:

public class ThreadPratice1 {

    public static void main(String[] args) {
        AtomicInteger number = new AtomicInteger(0);
        MyRunnable r = new MyRunnable(number);
        Thread t1 = new Thread(r, "Thread 1");
        Thread t2 = new Thread(r, "Thread 2");
        t1.start();
        t2.start();
    }
}

class MyRunnable implements Runnable {
    private AtomicInteger number;

    public MyRunnable(AtomicInteger number) {
        this.number = number;
    }

    @Override
    public void run() {
        while (number.get() < 10) {
            System.out.println("Thread: " + Thread.currentThread().getName()
                    + " value of i: " + number.getAndIncrement());
        }
    }
}

Upvotes: 0

Jos
Jos

Reputation: 2013

value of i is incremented by the for loop only after the loop is executed. Execution of for loop takes a finite amount of time. Since you are starting the threads together (almost), both the threads may or may not print i after the other thread has finished one loop. Since you are not doing to ensure thread safety, the result will be unpredictable like the one you got.

Upvotes: 0

Rock48
Rock48

Reputation: 92

You made "i" static, which means it will be the same over all threads and objects. Take away the static modifier and your code will work properly.

edit: I misinterpreted what you asked- don't set i to 0 in the for loop, it will look something like this:

for(;i<10;i++) { /*mycode*/}

One of these two is probably what you want anyway, your question was a little bit vague

Upvotes: 2

Salah
Salah

Reputation: 8657

Because the value of i at the begging of the execution of the two threads is 0.

In other words, thread one and thread two stared almost at the same time, so the two of them set the i to 0 for the first loop.

for(i = 0; i <10;i++) {

Then the value changes between thread because you made i static. so it will be shared between your two threads.

Upvotes: 2

Related Questions