java - 使用 ThreadLocal 为每个线程分配 ID

标签 java multithreading threadpool threadpoolexecutor

在下面的程序中,我想为每个线程分配不同的 ID,但在输出中每个线程都具有不一致的 ID,如输出所示。但是,如果我取消对 system.out 语句的注释,则每个线程都被分配了唯一的 ID,不确定原因。

class ThreadLocalDemo {
public static void main(String[] args) throws InterruptedException, 
ExecutionException {
    CustomerThread custThread1 = new CustomerThread("Sampath");
    CustomerThread custThread2 = new CustomerThread("Harish");
    CustomerThread custThread3 = new CustomerThread("Harsha");
    CustomerThread custThread4 = new CustomerThread("Gowtham");
    custThread1.start();
    custThread2.start();
    custThread3.start();
    custThread4.start();
    }
}

class CustomerThread extends Thread {
static Integer custId = 0;
private  static ThreadLocal<Integer> tl = new ThreadLocal<Integer>() {
    @Override
    protected Integer initialValue() {
        //System.out.println("will work");
        return ++custId;
    }
};

CustomerThread(String name) {
    super(name);
}

public void run() {
    System.out.println(Thread.currentThread().getName() + " executing with id: " + tl.get());
}
}

输出是:

Sampath executing with id: 1
Harish executing with id: 
Harsha executing with id: 2
Gowtham executing with id: 1

预期输出是具有唯一 ID 的线程:

Sampath executing with id: 1
Harish executing with id: 2
Harsha executing with id: 3
Gowtham executing with id: 4              

最佳答案

您的代码不是线程安全的,因为 ++ 运算符不是线程安全的。

你应该使用 AtomicInteger , 并且没有理由使用 ThreadLocal .

将您的类(class)更改为此,以便在创建时分配 ID,即按照创建顺序,而不是推迟到第一次使用时:

class CustomerThread extends Thread {
    private static final AtomicInteger prevCustId = new AtomicInteger();
    private final int custId;

    CustomerThread(String name) {
        super(name);
        this.custId = prevCustId.incrementAndGet();
    }

    @Override
    public void run() {
        System.out.println(getName() + " executing with id: " + this.custId);
    }
}

示例输出

Sampath executing with id: 1
Harsha executing with id: 3
Gowtham executing with id: 4
Harish executing with id: 2

关于java - 使用 ThreadLocal 为每个线程分配 ID,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44338430/

相关文章:

java - 使用JDBC和MySQL解决“通信链接失败”问题

java - 登录一个json文件

python - Python2.7中带超时的锁

c# - 为什么线程 2 不可用?

无限迭代器上的Python线程/进程池?

c# - 什么时候在 C# 中使用线程池?

java - Android中LocationListener的SettableFuture block 事件

java - 向外部 H2 数据库添加聚合函数

multithreading - Forth 支持多线程吗?

c++ - 我可以在多核 x86 CPU 上强制缓存一致性吗?