歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Java多線程之ThreadLocal

Java多線程之ThreadLocal

日期:2017/3/1 10:26:16   编辑:Linux編程

下面是ThreadLocal的測試代碼,更多信息請參考注釋

  1. package com.jadyer.thread.local;
  2. import java.util.Random;
  3. /**
  4. * ThreadLocal Test
  5. * @see =============================================================================================================
  6. * @see ThreadLocal的作用和目的
  7. * @see ThreadLocal用於實現線程內的數據共享。即對於相同的代碼,多個模塊在不同的線程中運行時,分別共享不同的數據
  8. * @see 每個線程調用全局的ThreadLocal.set()方法,就相當於在其內部的Map中增加一條記錄,key是各自的線程,value是各自set()傳進去的值
  9. * @see =============================================================================================================
  10. * @see ThreadLocal的應用場景
  11. * @see 例如Struts2中的ActionContext,同一段代碼被不同的線程調用運行時,該代碼操作的數據是每個線程各自的狀態和數據
  12. * @see 對於不同的線程來說,ActionContext.getContext()方法得到的對象都不相同
  13. * @see 對於同一個線程來說,ActionContext.getContext()方法無論在哪個模塊中或者是被調用多少次,其得到的都是同一個對象
  14. * @see 通過查看com.opensymphony.xwork2.ActionContex的第43和166行源碼,不難發現,Struts2就是這麼做的
  15. * @see =============================================================================================================
  16. * @see 線程中的成員變量和局部變量
  17. * @see 成員變量:多個線程操作同一個對象的成員變量時,它們對成員變量的改變是彼此影響的
  18. * @see 局部變量:每個線程都會有一個該局部變量的拷貝,一個線程對局部變量的改變不會影響到其它線程對該局部變量的操作
  19. * @see =============================================================================================================
  20. * @author 宏宇
  21. * @create Feb 27, 2012 12:10:24 AM
  22. */
  23. public class ThreadLocalTest {
  24. public static void main(String[] args) {
  25. new Thread(new MyThread(new Random().nextInt())).start();
  26. new Thread(new MyThread(new Random().nextInt())).start();
  27. }
  28. }
  29. class MyThread implements Runnable{
  30. private Integer data;
  31. public MyThread(Integer data){
  32. this.data = data;
  33. }
  34. @Override
  35. public void run() {
  36. System.out.println(Thread.currentThread().getName() + " has put data:" + data);
  37. User.getThreadInstance().setName("name" + data);
  38. User.getThreadInstance().setAge(data);
  39. new Pig().getMyData();
  40. new Dog().getMyData();
  41. }
  42. }
  43. class Pig{
  44. public void getMyData(){
  45. User user = User.getThreadInstance();
  46. System.out.println("Pig from " + Thread.currentThread().getName() + " getMyData:" + user.getName() + "|" + user.getAge());
  47. }
  48. }
  49. class Dog{
  50. public void getMyData(){
  51. User user = User.getThreadInstance();
  52. System.out.println("Dog from " + Thread.currentThread().getName() + " getMyData:" + user.getName() + "|" + user.getAge());
  53. }
  54. }
  55. /**
  56. * 自定義的線程范圍內共享的對象。即該類會針對不同的線程分別創建一個獨立的對象
  57. * @see 此時每個線程得到的將是自己的實例,各線程間得到的實例沒有任何關聯
  58. * @see 我們可以拿它,與單例模式中的懶漢式,進行對比,這是個很有意思的東西
  59. * @see Struts2就是這麼設計的,它的每一個請求就是一個線程
  60. */
  61. class User{
  62. private static ThreadLocal<User> instanceMap = new ThreadLocal<User>();
  63. private User(){}
  64. /**
  65. * 得到與當前線程相關的,當前類的實例
  66. */
  67. public static /*synchronized*/ User getThreadInstance(){
  68. User instance = instanceMap.get();
  69. if(null == instance){
  70. instance = new User();
  71. instanceMap.set(instance);
  72. }
  73. return instance;
  74. }
  75. private String name;
  76. private int age;
  77. public String getName() {
  78. return name;
  79. }
  80. public void setName(String name) {
  81. this.name = name;
  82. }
  83. public int getAge() {
  84. return age;
  85. }
  86. public void setAge(int age) {
  87. this.age = age;
  88. }
  89. }
Copyright © Linux教程網 All Rights Reserved