在 MultiThread 的世界裡面,Thread 和 Thread 之間本來就井水不河水,
要存取共用的資源時,就要透過鎖定同步等方式,才不會有競速的問題,
TLS 要解決的問題,並不是 Thread 之間資源共享的問題,
而是 Thread 本身資源共享的問題。
假設我們要設計一個 ADODB 物件,
讓程式都透過底層取得 ADODB 物件,再使用 ADODB 物件執行 SQL ,
而 Connection 的事都交給 ADODB 物件處理,
程式只需要
ADODB dbAdpter = ADODBFactory.getADODB();而 ADODB 物件的設計,會盡量使用同一條 Connection ,
dbAdpter.execSQL(...);
如上面程式所示,void main(){methodA();methodB();}void methodA() {ADODB dbAdpter = ADODBFactory.getADODB();dbAdpter.execSQL("...");}void methodB() {ADODB dbAdpter = ADODBFactory.getADODB();dbAdpter.execSQL("...");}
這邊會希望每次從 ADODBFactory.getADODB() 取出來的物件是同一個,
而 connection 就 keep 在這裡面,
對 ADODBFactory 而言,並不曉得呼叫他的是不是同一個 thread ,
他也不能隨便丟一個 ADODB 回去,如果每次都 new 一個 ADODB 的話,
就變成會開一堆 connection ,即使有用 ado.net 的 connection pooling ,
connection 用量還是很大,更慘的是,如果有 transctionscope 還會被升級成 DTC,
如果 ADODBFactory 能夠從 thread 中取得現有的 ADODB ,
沒有的時候就 new 一個給他,這樣就完美了,
所以我們需要在 thread 中佈置一塊空間,而且讓 thread 外面可以看得到,拿得到,
這時候 TLS 就很好用了,直接就在 thread 上放一個俱名的 Data Slot ,
ADODBFactory.getADODB 就先看目前 thread 裡有沒有存在的 ADODB 物件,
如果有就直接拿,沒有的話就 new 一個給他。
於是我們就很輕鬆的用 TLS 完成這個任務了。public static ADODB getADODB(){if (Thread.GetData(Thread.GetNamedDataSlot("YourDataSlotID"))==null) {Thread.SetData(Thread.GetNamedDataSlot("YourDataSlotID"), newADODB());}return (ADODB)Thread.GetData(Thread.GetNamedDataSlot("YourDataSlotID"));}
參考資料:
Thread Local Storage: Thread-Relative Static Fields and Data Slots
沒有留言 :
張貼留言