如何在池线程中正确使用ThreadLocal?

问题描述 投票:0回答:1

Java并发实践说:

ThreadLocal仅在线程本地值的生存期受任务限制的情况下才可以在池线程中使用;不应在池线程中使用ThreadLocal在任务之间传递值。

我对以上引用的理解是:ThreadLocalRunnablerun()末尾应清楚。我说的对吗?

下面的代码片段显示了当您忘记清除时的问题。

package com.example.schedulerdemo;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class EndlessShutdownHook {

    public static void main(String[] args) {
        ExecutorService executorService = Executors.newSingleThreadExecutor();
        ThreadLocal<String> cache = new ThreadLocal<>();

        executorService.execute(new AuthenticationTask("1234", cache));
        executorService.execute(new AuthenticationTask("5678", cache)); // expect to print 5678, but print 1234

        executorService.shutdown();
    }
}

class AuthenticationTask implements Runnable {

    private final String token;

    private final ThreadLocal<String> threadLocal;

    AuthenticationTask(String token, ThreadLocal<String> cache) {
        this.token = token;
        this.threadLocal = cache;
    }

    @Override
    public void run() {
        String username = threadLocal.get();
        if (null != username) {
            System.out.printf("username: %s\n", username);
        } else {
            if (null != token) {
                username = getUsernameByToken(token);
                threadLocal.set(username);
                System.out.printf("username: %s\n", username);
            } else {
                System.out.println("token is null");
            }
        }

        // execute other logic after authenticating

        // forget to clear ThreadLocal
    }

    private String getUsernameByToken(String token) {
        return token;
    }
}
java thread-local
1个回答
© www.soinside.com 2019 - 2024. All rights reserved.