简体   繁体   English

ThreadLocal和列表不起作用

[英]ThreadLocal and list doesn't work

I'm having a problem with my ThreadLocal based class. 我的ThreadLocal类有问题。 Any help would be appreciated. 任何帮助,将不胜感激。 This is a base class with a simple list of somethings: 这是一个基类,包含一些简单的列表:

public class ThreadLocalTest {

protected static final ThreadLocal<List<String>> thList = new ThreadLocal<List<String>>() {
    protected List<String> initialValue() {
        return new ArrayList<String>();
    }
};

public static void put(String k) {
    thList.get().add(k);
}

public static List<String> getList() {
    return thList.get();
}

}

I'm testing it in this way: 我正在以这种方式测试它:

Thread th1 = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("------------------thread1---------------------------");
                ThreadLocalTest.put("a");
                ThreadLocalTest.put("b");
                List<String> l = ThreadLocalTest.getList();
                System.out.println(l.size());
                System.out.println("----------------------------------------------------");
            }
        });
        Thread th2 = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("------------------thread2---------------------------");
                ThreadLocalTest.put("c");
                List<String> l = ThreadLocalTest.getList();
                System.out.println(l.size());
                System.out.println("----------------------------------------------------");
            }
        });
        th1.run();
        th2.run();
        th1.run();
        th2.run();
        th1.run();
        th2.run();
        th1.run();
        th2.run();

So what I get is: 所以我得到的是:

------------------thread1---------------------------
2
----------------------------------------------------
------------------thread2---------------------------
3
----------------------------------------------------
------------------thread1---------------------------
5
----------------------------------------------------
------------------thread2---------------------------
6
----------------------------------------------------
------------------thread1---------------------------
8
----------------------------------------------------
------------------thread2---------------------------
9
----------------------------------------------------
------------------thread1---------------------------
11
----------------------------------------------------
------------------thread2---------------------------
12
----------------------------------------------------

You see that it seems these threads actually share the very same list, but I dont understand why. 你看,似乎这些线程实际上共享相同的列表,但我不明白为什么。

Any tips? 有小费吗?

You invoke run() method instead of start() . 您调用run()方法而不是start() run() runs in the same thread it is invoked, while start() invokes run() in a new, separate thread. run()在调用它的同一个线程中运行,而start() run()在一个新的独立线程中调用run() In effect, all your "threads" are executed in the same thread. 实际上,所有“线程”都在同一个线程中执行。

There are two issues here. 这里有两个问题。

1) you can't cause a new Thread to execute by calling the run method directly. 1)您不能通过直接调用run方法来执行新的Thread This skips the "magic" and just calls the run method within your main thread. 这会跳过“魔术”并在主线程中调用run方法。 Everything you are seeing is happening in the same thread as a result, and so there is only one single ThreadLocal list. 您看到的所有内容都发生在同一个线程中,因此只有一个ThreadLocal列表。

To cause a new Thread to execute you have to call start 要使新Thread执行,您必须调用start

2) you can't call 'start' multiple times on the same Thread , so you can't test the multiple calling you are trying. 2)你不能在同一个Thread上多次调用'start',因此你无法测试你正在尝试的多次调用。 You would have to create new Thread objects each time, but this will mean, they obviously do not share the ThreadLocal variable, which I guess you are trying to test 你必须每次都创建新的Thread对象,但这意味着,他们显然不会共享ThreadLocal变量,我猜你试图测试

You see that it seems these threads actually share the very same list, but I dont understand why. 你看,似乎这些线程实际上共享相同的列表,但我不明白为什么。

The reason is that you're not actually creating any new threads. 原因是你实际上并没有创建任何新线程。 All of your code is running using the main thread (and so, the behaviour you see is completely expected). 所有代码都使用主线程运行(因此,您看到的行为是完全可以预期的)。

You need to start the new thread of execution running: 您需要启动正在运行的新线程:

Replace: 更换:

th1.run();
th2.run();
th1.run();
th2.run();
th1.run();
th2.run();
th1.run();
th2.run();

With: 附:

th1.start();
th2.start();

Watch out when trying to interpret your output however. 但是在尝试解释输出时要小心。 Since the threads will be running concurrently, the writes to the console could be intermixed. 由于线程将同时运行,因此可以混合对控制台的写入。

并且你不能在启动后删除相同的Thread对象,你必须重新创建它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM