我有一个标有ThreadStaticAttribute
的字段。它在主线程中被初始化,但是我的代码使用了很多async/await
结构和Parallel
库,这就是为什么我不知道要执行多少个线程的原因。我想确保每个线程都将此字段初始化。我该怎么做?如何初始化线程池中每个新线程标记为ThreadStaticAttribute的静态字段?
3
A
回答
4
随着ThreadStaticAttribute
你不能以你想要的方式执行初始化。 Actully,文档指出你不应该执行在所有的初始化:
的字段标有 ThreadStaticAttribute不要指定初始值,因为这样的初始化类的构造函数执行时只发生一次, ,因此只影响一个 线程
但是,您可以使用替代:ThreadLocal<T>
:
private ThreadLocal<string> _myVar = new ThreadLocal<string>(() => "some string");
var s = _myVar.Value; // separate for each thread
_myVar.Value = "changed";
请注意,ThreadLocal<T>
执行IDisposable
,因此必须在您完成后处置。
您也可以实现ThreadStatic
字段的单独访问器,该字段将首先检查字段是否已初始化,如果未初始化,则初始化该字段,然后返回值(类似于单例模式)。由于ThreadStatic
字段,因此不需要任何锁就可以线程安全。
另请注意,使用ThreadStatic
或ThreadLocal
与线程池线程(就像您一样)可能会导致令人惊讶的行为,因为当线程返回到池时本地线程存储不会被清除。所以你可能会“开始”一个新的线程(当真正的线程退出池中时),并且该线程可能已经在上一次迭代中留下的`ThreadLocal`字段中具有值ThreadStatic
。
相关问题
- 1. 初始化静态块中的线程?
- 2. 全局静态初始化线程
- 3. 什么线程正在初始化静态字段?
- 4. 静态字段初始化
- 5. C++,是由多个线程执行的静态初始化?
- 6. 如何初始化Kotlin中的线程?
- 7. C++中的静态初始化和线程安全
- 8. 线程池中的线程状态
- 9. 如何使用线程池来处理新线程中的每个连接
- 10. 多线程 - 新线程vs线程池
- 11. 初始化主线程
- 12. 如何初始化多线程上下文中的静态变量?
- 13. Rayon中的每个线程的初始化
- 14. 内部非线程安全字符串变体和静态初始化程序
- 15. 等待初始化池中的所有线程
- 16. 静态初始化器和线程同步(.NET)
- 17. 线程安全Singletion静态方法初始化
- 18. C++静态变量初始化和线程
- 19. asm中的静态初始化程序
- 20. 静态初始化程序中的Task.Run
- 21. 无法初始化线程构造函数中的PrintWriter字段
- 22. 如何创建多个线程池(即多个执行程序,每个线程池都有一个线程)
- 23. 线程化类成员函数;线程初始化通过初始化列表
- 24. 线程池中的线程
- 25. NotesContext未初始化为线程
- 26. 如何使用ASM为初始化程序添加静态最终字段?
- 27. 使用jboss5线程池开始线程
- 28. 静态字段无法初始化
- 29. 通用静态字段初始化
- 30. 静态字段/属性初始化
您可以在首次访问时初始化它(即 - 您想读取值,请参阅字段尚未初始化 - 初始化它)。 – Evk
@Evk在访问之前有什么方法可以初始化它吗? –
我不这么认为。实际上初始化它是不鼓励的,因为docs声明:“不要为用ThreadStaticAttribute标记的字段指定初始值,因为这种初始化只发生一次,当类构造函数执行时,因此只影响一个线程。”我想,你可以使用'ThreadLocal'来做你想做的事。 –
Evk