Skip to content
Advertisement

Why initialValue of ThreadLocal doesn’t increment my variables?

I am learning about multithreading; and I have the following ThreadID class:

public class ThreadID {

    private static volatile int nextID=0;

    private static class ThreadLocalID extends ThreadLocal<Integer>{
        protected synchronized Integer initialValue(){
            return nextID ++;
        }
    }

    private static ThreadLocalID threadID =new ThreadLocalID();

    public static int get(){
        return threadID.get();
    }

    public static void set (int index){
        threadID.set(index);
    }
}

and the following Thread class:

class MyThread1 extends Thread {
    int x;
    public ThreadID tID;
    public int myid;

    public MyThread1(String name) {
        tID = new ThreadID();
        myid = tID.get();
    }

    public void run() {
        System.out.println("la thread =" + tID.get() + " myid= " + myid);
        try {
            this.sleep(10);
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("la thread =" + tID.get() + "   apres le sommeil ");
    }
}

and my main Class:

public static void main(String[] args) {
    MyThread1 TH[] = new MyThread1[10];
    for (int i = 0; i < 10; i++)
        TH[i] = new MyThread1("nom" + i);
    try {
        for (int i = 0; i < 10; i++) TH[i].start();
        for (int i = 0; i < 10; i++) TH[i].join();
    } catch (InterruptedException e) {
    }
}

Question:

What I want is to give each Thread an ID; I found that when I init the id in the thread constructor the value is always 0 (normally the initialValue should increment the nextID)

la thread =1 myid= 0
la thread =3 myid= 0
la thread =2 myid= 0

but when I init the id inside the Run function it works !

la thread =1 myid= 1
la thread =3 myid= 3
la thread =2 myid= 2

Can any one explain why this happens?

Advertisement

Answer

What I want is to give each Thread an ID I found that when I init the id in the thread constructor the value is always 0 (normally the initialValue should increment the nextID)

So in the MyThread1 class constructor you do:

public MyThread1(String name) {
    tID = new ThreadID();
    myid = tID.get();
}

In this case, the thread actually calling tID.get(); is the main thread, i.e., the thread that is calling those constructors, from the main class:

MyThread1 TH[] = new MyThread1[10];
for (int i = 0; i < 10; i++)
    TH[i] = new MyThread1("nom" + i); 

The first call to tID.get() will generate a new ID as 0, since it is the first time that any thread is calling tID.get(). The next calls from the same thread (i.e., main thread) will not generate a new ID, but instead, it always returns the same ID, in this case, return 0 for the main thread.

but when I init the id inside the Run function it works!

Inside the run method:

public void run() {
    System.out.println("la thread =" + tID.get() + " myid= " + myid);
    try {
        this.sleep(10);
    } catch (Exception e) {
        e.printStackTrace();
    }
    System.out.println("la thread =" + tID.get() + "   apres le sommeil ");
}

the tID.get() will be called by different threads, and that is why you get new IDs. One new ID per thread calling for the first time tID.get().

8 People found this is helpful
Advertisement