0

I ran following java code to test multithreading. I would like to make each thread increments the index variable by 1. But following doesn't work.

public class start {
    public static void main(String[] args) {
        // TODO Auto-generated method stub

        Thread[] threadList = new Thread[20];

        for (int i = 0; i < 20; i++) {
            threadList[i] = new worker();
            threadList[i].start();
        }
    }
}

public class worker extends Thread {
    private static int index = 0;

    public static synchronized int getIndex() {
        return index++;
    }

    public void run() {
        index = getIndex();
        System.out.println("Thread Name: "+Thread.currentThread().getName() + "index: "+index);
    }
}

It gives me following result:

Thread Name: Thread-0index: 0
Thread Name: Thread-2index: 0
Thread Name: Thread-4index: 0
Thread Name: Thread-1index: 0
Thread Name: Thread-6index: 0
Thread Name: Thread-8index: 0
Thread Name: Thread-5index: 0
Thread Name: Thread-7index: 0
Thread Name: Thread-3index: 0
Thread Name: Thread-9index: 0
Thread Name: Thread-13index: 0
Thread Name: Thread-11index: 0
Thread Name: Thread-12index: 0
Thread Name: Thread-10index: 0
Thread Name: Thread-14index: 0
Thread Name: Thread-17index: 0
Thread Name: Thread-15index: 0
Thread Name: Thread-19index: 0
Thread Name: Thread-16index: 0
Thread Name: Thread-18index: 0

Index value did not change. How to fix this issue?

2
  • 3
    return index++; is returning the value of index and incrementing it afterwards, since you assign it back, you'll get the same old value for index Commented Jan 21, 2015 at 14:48
  • annotate your run() method with @Override as you are extending the behaviour of run() method from Parent class Thread. Commented Jan 21, 2015 at 14:49

3 Answers 3

4

This assignment is resetting the value of index (and is unsynchronized):

index = getIndex();

overriding the effect of the increment operator. A possible solution would be to store the result of getIndex() in a local variable:

final int i = getIndex();
System.out.println("Thread Name: "                  +
                   Thread.currentThread().getName() +
                   "index: "                        +
                   i);

"implements Runnable" vs. "extends Thread"

Sign up to request clarification or add additional context in comments.

Comments

0

For this simple program to increment index number for each Thread invocation, AtomicInteger variable would be suffice.

An int value that may be updated atomically. See the java.util.concurrent.atomic package specification for description of the properties of atomic variables. An AtomicInteger is used in applications such as atomically incremented counters, and cannot be used as a replacement for an Integer.

Corrected code:

import java.util.concurrent.atomic.AtomicInteger;

public class ThreadDemo {
    public static void main(String[] args) {
        // TODO Auto-generated method stub

        Thread[] threadList = new Thread[20];

        for (int i = 0; i < 20; i++) {
            threadList[i] = new worker();
            threadList[i].start();
        }
    }
}

class worker extends Thread {
    private static AtomicInteger index = new AtomicInteger(0);

    private int getIntValueOfIndex(){
        return index.incrementAndGet();
    }

    public void run() {
       System.out.println("Thread Name: "+Thread.currentThread().getName() + "index: "+getIntValueOfIndex());
    }
}

Comments

-1

index = getIndex(); is not atomic. Reads and writes to shared data must be synchronized.

Delete this line and change +index in run() to getIndex() and see what happens.

1 Comment

Nothing to do with being atomic or not.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.