微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么 ThreadLocal 的 initialValue 不会增加我的变量?

如何解决为什么 ThreadLocal 的 initialValue 不会增加我的变量?

我正在学习多线程;我有以下 ThreadID 类:

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);
    }
}

以及以下 Thread 类:

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 ");
    }
}

和我的 main 班级:

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) {
    }
}

问题:

我想要的是给每个线程一个ID;我发现当我在线程构造函数中初始化 id 时,值总是 0(通常 initialValue 应该增加 nextID

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

但是当我在 id 函数中初始化 Run 时它可以工作!

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

谁能解释为什么会发生这种情况?

解决方法

我想要的是给每个线程一个我在初始化时发现的 ID 线程构造函数中的 id 值始终为 0(通常是 initialValue 应该增加 nextID)

因此在 MyThread1 类构造函数中,您执行以下操作:

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

在这种情况下,实际调用 tID.get(); 的线程是 main 线程,,从主类调用这些构造函数的线程:

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

tID.get() 的第一次调用将生成一个新的 ID 作为 0,因为这是任何线程第一次调用 tID.get()。来自同一线程(ie, 主线程)的下一次调用不会生成新的 ID,而是始终返回相同的 ID,在这种情况下,返回 {{1} } 用于线程。

但是当我在 Run 函数中初始化 id 时它起作用了!

0 方法内部:

run

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 "); } 将被不同的线程调用,这就是您获得新 ID 的原因。 每个线程第一次调用一个新 ID tID.get()

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。