線程範圍內資料共用

來源:互聯網
上載者:User

用處:處理資料庫中交易管理員較為常用,所有的操作都是針對同一份資料。系統角度進行開發編程。

 

第一種方法,這種方法比較粗糙

public class ThreadScopeShareData {              private static int data = 0;       private static Map<Thread , Integer> threadData = new HashMap<Thread,Integer>();       public static void main(String[] args){              for (int i = 0; i < 2; i++) {                     new Thread(new Runnable(){                            public void run(){                                   data = new Random().nextInt();                                   System.out.println(Thread.currentThread().getName()                                                 + " has put data :"+data);                                   threadData.put(Thread.currentThread(),data);                                   new A().get();                                   new B().get();                            }                     }).start();              }       }              static class A{              public void get(){                     data = threadData.get(Thread.currentThread());                     System.out.println("A from "+ Thread.currentThread().getName()+" get data :"+data);              }       }              static class B{              public void get(){                     data = threadData.get(Thread.currentThread());                     System.out.println("B from "+ Thread.currentThread().getName()+" get data :"+data);              }       }}

 

 

 

 

 

 

第二種方法:ThreadLocal,該類相當於一個Map

public class ThreadLocalTest {              static final ThreadLocal<Integer> x = new ThreadLocal<Integer>();       public static void main(String[] args){              for (int i = 0; i < 2; i++) {                     new Thread(new Runnable(){                            public void run(){                                   int data = new Random().nextInt()/10000000;                                   System.out.println(Thread.currentThread().getName()                                                 + " has put data :"+data);                                   x.set(data);                                   new A().get();                                   new B().get();                            }                     }).start();              }       }              static class A{              public void get(){                     int data = x.get();                     System.out.println("A from "+ Thread.currentThread().getName()+" get data :"+data);              }       }              static class B{              public void get(){                     int data = x.get();                     System.out.println("B from "+ Thread.currentThread().getName()+" get data :"+data);              }       }}

 

第三種方法:操作多個資料,不單單是基礎資料型別 (Elementary Data Type)。可以整合成一個實體物件,然後往ThreadLocal中set這個對象。

public class ThreadLocalTest {              private static final ThreadLocal<Integer> x = new ThreadLocal<Integer>();       private static final ThreadLocal<MyThreadScopeData> myThreadScopeData = new ThreadLocal<MyThreadScopeData>();              public static void main(String[] args){              for (int i = 0; i < 2; i++) {                     new Thread(new Runnable(){                            public void run(){                                   int data = new Random().nextInt()/10000000;                                   System.out.println(Thread.currentThread().getName()                                                 + " has put data :"+data);                                   x.set(data);                                   MyThreadScopeData myData = new MyThreadScopeData();                                   myData.setName(" name "+data);                                   myData.setAge(data);                                   myThreadScopeData.set(myData);                                   new A().get();                                   new B().get();                            }                     }).start();              }       }              static class A{              public void get(){                     int data = x.get();                     System.out.println("A from "+ Thread.currentThread().getName()+" get data :"+data);                     MyThreadScopeData myData = myThreadScopeData.get();                     System.out.println("A from "+ Thread.currentThread().getName()+" getMydata :"+myData.getName()+","+myData.getAge());              }       }              static class B{              public void get(){                     int data = x.get();                     System.out.println("B from "+ Thread.currentThread().getName()+" get data :"+data);                     MyThreadScopeData myData = myThreadScopeData.get();                     System.out.println("B from "+ Thread.currentThread().getName()+" getMydata :"+myData.getName()+","+myData.getAge());              }       }} class MyThreadScopeData{       private String name;       private int age;       public String getName() {              return name;       }       public void setName(String name) {              this.name = name;       }       public int getAge() {              return age;       }       public void setAge(int age) {              this.age = age;       }       }

 

第四種方式:很優雅的處理辦法,仿單例模式處理。ThradLocal類放到實體類的背後了,設計也交給了實體類,調用者不需要關心實體類的設計,只需要get到實體類的執行個體對象即可,同一線程內,任何地方調用實體類的執行個體對象,都是同一個執行個體對象,操作的資料都是同一份,也就達到了線程內資料共用的效果。該處理方法很好的體現了物件導向的思想。

strust2也是如此的設計方式。

public class ThreadLocalTest {              private static final ThreadLocal<Integer> x = new ThreadLocal<Integer>();       private static final ThreadLocal<MyThreadScopeData> myThreadScopeData = new ThreadLocal<MyThreadScopeData>();              public static void main(String[] args){              for (int i = 0; i < 2; i++) {                     new Thread(new Runnable(){                            public void run(){                                   int data = new Random().nextInt()/10000000;                                   System.out.println(Thread.currentThread().getName()                                                 + " has put data :"+data);                                   x.set(data);                                   MyThreadScopeData.getThreadInstance().setName(" name "+data);                                   MyThreadScopeData.getThreadInstance().setAge(data);                                   new A().get();                                   new B().get();                            }                     }).start();              }       }              static class A{              public void get(){                     int data = x.get();                     System.out.println("A from "+ Thread.currentThread().getName()+" get data :"+data);                     MyThreadScopeData myData = MyThreadScopeData.getThreadInstance();                     System.out.println("A from "+ Thread.currentThread().getName()+" getMydata :"+myData.getName()+","+myData.getAge());              }       }              static class B{              public void get(){                     int data = x.get();                     System.out.println("B from "+ Thread.currentThread().getName()+" get data :"+data);                     MyThreadScopeData myData = MyThreadScopeData.getThreadInstance();                     System.out.println("B from "+ Thread.currentThread().getName()+" getMydata :"+myData.getName()+","+myData.getAge());              }       }} class MyThreadScopeData{       private MyThreadScopeData(){};              private static ThreadLocal<MyThreadScopeData> map = new ThreadLocal<MyThreadScopeData>();              public static MyThreadScopeData getThreadInstance(){              MyThreadScopeData instance = map.get();              if(instance == null){                     instance = new MyThreadScopeData();                     map.set(instance);              }              return instance;       }              private String name;       private int age;       public String getName() {              return name;       }       public void setName(String name) {              this.name = name;       }       public int getAge() {              return age;       }       public void setAge(int age) {              this.age = age;       }       }

 

使用ThreadLocal類:

       類似於一種棧機制,不同的線程在其有不同的記錄,當時間一久,越積越多,提供clean()方法供清理。當然其內部可以自動進行回收,不用擔心如果自己不處理會溢出問題。線程一完成,則會自動回收對應的執行個體對象的引用。如果不同的ThreadLocal對象中,同一線程有記錄,則當該線程處理完後,這些不同的ThreadLocal對象中的記錄都會被回收,除非該線程對應的執行個體對象有其他的線程所關聯操作。詳細查詢jdk文檔。

 

提問:如何控制線程死亡狀態?

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.