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().

User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement