0

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?

4 Answers4

2

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.

Salah
  • 8,567
  • 3
  • 26
  • 43
  • Ok. But when the first thread get executed shouldn't it increase the value to 1. Thus when the second thread gets chance shouldn't it print 1 ? – Abhiroop Nandi Ray Nov 11 '15 at 14:16
  • No, it will not increase the value to 1 at the first enter, since you re-initializing the `i` again by saying `for(i = 0; i <10;i++) {` – Salah Nov 11 '15 at 14:19
2

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

Rock48
  • 72
  • 1
  • 8
0

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.

Jos
  • 2,015
  • 1
  • 17
  • 22
0

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());
        }
    }
}
Community
  • 1
  • 1
chengpohi
  • 14,064
  • 1
  • 24
  • 42