java多线程之Thread-Specific Storage模式
一、Thread-Specific Storage模式
Specific是特定的意思,Storage模式是儲存柜的意思,因為所謂Thread-Specific Storage就是“每個線程特有的儲物柜”“為每個線程準備儲存空間”的意思。
Thread-Specific Storage模式是一種即使只有一個入口,也會在內(nèi)部為每個線程分配特有的儲存空間的模式。
二、關(guān)于java.lang.ThreadLocal類(就是儲物間)
將java.lang.ThreadLocal的實例當作一種集合可能會有助于理解它,也就是說ThreadLocal的實例會管理多個對象。
- set方法
 
ThreadLocal類的set方法用戶將通過參數(shù)接收的實例與調(diào)用該方法的線程對應并存儲起來,這里存儲的對象可以通過get方法獲取,set方法中沒有表示線程的參數(shù),set方法會先查詢當前線程,然后以它作為鍵來存儲實例。
調(diào)用set方法相當于將自己的行李放置到自己的存物柜中。
- get方法
 
ThreadLocal類的get方法用戶獲取與調(diào)用get方法的線程(當前線程)對應的實例,該線程之前通過set方法存儲的實例就是get方法的返回值,如果之前一次都還沒有調(diào)用過set方法,則get方法的返回值為null。
與set方法一樣,get方法中也沒有表示線程的參數(shù),因為,get方法也會去查詢當前線程,即get方法會以當前線程自身作為鍵去獲取對象。
調(diào)用get方法相當于從自己的儲物柜中取出自己的行李。
public class ThreadLocal<T> { //存儲 public void set(T value) { ... } //獲取 public T get() { ... } ...}即通過ThreadLocal的T指定的類型就是set方法的參數(shù)的類型以及get方法的返回值的類型。
三、不使用Thread-Specific Storage模式示例程序
1.示例程序一覽表
| Log.java | 創(chuàng)建日志的類 | 
| Main.java | 測試示例程序的類 | 
2.示例程序的類圖
3.Log類
package com.viagra.Thread_Specific_Storage_Pattern.Lesson1;import java.io.FileWriter; import java.io.IOException; import java.io.PrintWriter;/*** @Auther: viagra* @Date: 2019/11/19 20:22* @Description:*/ public class Log {/*** 是用于在名為log.txt的文件中記錄程序運行記錄的類。* writer字段中保存的是用于寫文件的java.io.PrintWriter的實例。* println方法是用于將通過參數(shù)接收到的字符串寫入到文件中的方法。* close方法是用于關(guān)閉日志文件的方法。*/private static PrintWriter writer = null;//初始化writer字段static {try {writer = new PrintWriter(new FileWriter("log.txt"));} catch (IOException e) {e.printStackTrace();}}//寫日志public static void println(String s) {writer.println(s);}//關(guān)閉日志public static void close() {writer.println("===end of log===");writer.close();} }4.Main類
package com.viagra.Thread_Specific_Storage_Pattern.Lesson1;/*** @Auther: viagra* @Date: 2019/11/19 20:22* @Description:*/ public class Main {public static void main(String[] args) {System.out.println("Begin");for (int i = 0; i < 10; i++) {Log.println("main: i = " + i);try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}Log.close();System.out.println("End");} }5.運行結(jié)果
Begin End //for循環(huán)中設置的等待時間是1s,這里大約10s后顯示6.文件內(nèi)容
main: i = 0 main: i = 1 main: i = 2 main: i = 3 main: i = 4 main: i = 5 main: i = 6 main: i = 7 main: i = 8 main: i = 9 ===end of log===7.示例程序的Timethreads圖
四、使用Thread-Specific Storage模式示例程序
1.示例程序類的一覽表
| TSLog.java | 創(chuàng)建日志的類(實例屬于各個線程所有) | 
| Log.java | 創(chuàng)建日志的類(分配各個線程) | 
| java.lang.ThreadLocal | 分配線程特有的存儲空間的類 | 
| ClientThread.java | 表示調(diào)用Log的線程的類 | 
| Main | 測試示例程序的類 | 
2.示例程序的類圖
3.TSLog類
package com.viagra.Thread_Specific_Storage_Pattern.Lesson2; import java.io.FileWriter; import java.io.IOException; import java.io.PrintWriter;public class TSLog {private PrintWriter writer = null;//初始化writer字段public TSLog(String filename) {try {writer = new PrintWriter(new FileWriter(filename));} catch (IOException e) {e.printStackTrace();}}//寫日志public void println(String s) {writer.println(s);}//關(guān)閉日志public void close() {writer.println("=== End of log ===");writer.close();} }4.Log類
package com.viagra.Thread_Specific_Storage_Pattern.Lesson2;public class Log {private static final ThreadLocal<TSLog> tslogCollection = new ThreadLocal<TSLog>();//寫日志public static void println(String s) {getTSLog().println(s);}//關(guān)閉日志public static void close() {getTSLog().close();}//獲取線程特有的日志private static TSLog getTSLog() {TSLog tsLog = tslogCollection.get();//如果該線程是第一次調(diào)用本方法,就新生成并注冊一個日志if (tsLog == null) {tsLog = new TSLog(Thread.currentThread().getName() + "-log.txt");tslogCollection.set(tsLog);}return tsLog;} }5.ClientThread類
package com.viagra.Thread_Specific_Storage_Pattern.Lesson2;/*** @Auther: viagra* @Date: 2019/11/19 20:22* @Description:*/ public class ClientThread extends Thread {public ClientThread(String name) {super(name);}public void run() {System.out.println(getName() + " Begin");for (int i = 0; i < 10; i++) {Log.println(getName() + " i = " + i);try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}}Log.close();System.out.println(getName() + " End");} }6.Main類
package com.viagra.Thread_Specific_Storage_Pattern.Lesson2;/*** @Auther: viagra* @Date: 2019/11/19 20:27* @Description:*/ public class Main {public static void main(String[] args) {new ClientThread("Steve Nash").start();new ClientThread("Michael Jordan").start();new ClientThread("Ronaldo").start();} }7.運行結(jié)果
Steve Nash Begin Michael Jordan Begin Ronaldo Begin Michael Jordan End Steve Nash End Ronaldo End //這里分別創(chuàng)建了Michael Jordan-log.txt、Ronaldo-log.txt、Steve Nash-log.txt8.生成文件內(nèi)容
//如Michael Jordan-log.txt Michael Jordan i = 0 Michael Jordan i = 1 Michael Jordan i = 2 Michael Jordan i = 3 Michael Jordan i = 4 Michael Jordan i = 5 Michael Jordan i = 6 Michael Jordan i = 7 Michael Jordan i = 8 Michael Jordan i = 9 === End of log ===9.示例程序的Timethreads圖
五、Thread-Specific Storage模式中角色
1.Client(委托者)
Client角色將處理委托給TSObjectProxy角色,一個TSObjectProxy角色會被多個Client角色使用,是示例程序2中的ClientThread類。
2.TSObjectProxy(線程持有的對象的代理人)
TSObjectProxy角色會執(zhí)行多個Client角色委托給的處理。是示例程序2中的Log類。
3.TSObjectCollection(線程持有的對象的集合)
TSObjectCollection角色有一張Client角色與TSObject角色之間的對應表。是示例程序2中的java.lang.ThreadLocal類。
4.TSObject(線程持有的對象)
TSObject角色中保存著線程持有的信息,是示例程序2中的TSLog類。
5.Thread-Specific Storage模式的類圖
6.Thread-Specific Storage模式的時序圖
java多線程之Thread-Specific Storage模式
2018-02-24 14:25:27 更多
版權(quán)聲明:本文為博主原創(chuàng)文章,遵循 CC 4.0 BY-SA 版權(quán)協(xié)議,轉(zhuǎn)載請附上原文出處鏈接和本聲明。本文鏈接:https://blog.csdn.net/smartdt/article/details/79361099
一、Thread-Specific Storage模式
Specific是特定的意思,Storage模式是儲存柜的意思,因為所謂Thread-Specific Storage就是“每個線程特有的儲物柜”“為每個線程準備儲存空間”的意思。
Thread-Specific Storage模式是一種即使只有一個入口,也會在內(nèi)部為每個線程分配特有的儲存空間的模式。
二、關(guān)于java.lang.ThreadLocal類(就是儲物間)
將java.lang.ThreadLocal的實例當作一種集合可能會有助于理解它,也就是說ThreadLocal的實例會管理多個對象。
- set方法
 
ThreadLocal類的set方法用戶將通過參數(shù)接收的實例與調(diào)用該方法的線程對應并存儲起來,這里存儲的對象可以通過get方法獲取,set方法中沒有表示線程的參數(shù),set方法會先查詢當前線程,然后以它作為鍵來存儲實例。
調(diào)用set方法相當于將自己的行李放置到自己的存物柜中。
- get方法
 
ThreadLocal類的get方法用戶獲取與調(diào)用get方法的線程(當前線程)對應的實例,該線程之前通過set方法存儲的實例就是get方法的返回值,如果之前一次都還沒有調(diào)用過set方法,則get方法的返回值為null。
與set方法一樣,get方法中也沒有表示線程的參數(shù),因為,get方法也會去查詢當前線程,即get方法會以當前線程自身作為鍵去獲取對象。
調(diào)用get方法相當于從自己的儲物柜中取出自己的行李。
public class ThreadLocal<T> { //存儲 public void set(T value) { ... } //獲取 public T get() { ... } ...}即通過ThreadLocal的T指定的類型就是set方法的參數(shù)的類型以及get方法的返回值的類型。
三、不使用Thread-Specific Storage模式示例程序
1.示例程序一覽表
| Log.java | 創(chuàng)建日志的類 | 
| Main.java | 測試示例程序的類 | 
2.示例程序的類圖
3.Log類
public class Log { /** * 是用于在名為log.txt的文件中記錄程序運行記錄的類。 * writer字段中保存的是用于寫文件的java.io.PrintWriter的實例。 * println方法是用于將通過參數(shù)接收到的字符串寫入到文件中的方法。 * close方法是用于關(guān)閉日志文件的方法。 */ private static PrintWriter writer = null; //初始化writer字段 static { try { writer = new PrintWriter(new FileWriter("log.txt")); } catch (IOException e) { e.printStackTrace(); } } //寫日志 public static void println(String s) { writer.println(s); } //關(guān)閉日志 public static void close() { writer.println("===end of log==="); writer.close(); }}4.Main類
public class Main { public static void main(String[] args) { System.out.println("Begin"); for (int i = 0; i < 10; i++) { Log.println("main: i = " + i); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } Log.close(); System.out.println("End"); }}5.運行結(jié)果
BeginEnd //for循環(huán)中設置的等待時間是1s,這里大約10s后顯示6.文件內(nèi)容
main: i = 0main: i = 1main: i = 2main: i = 3main: i = 4main: i = 5main: i = 6main: i = 7main: i = 8main: i = 9===end of log===7.示例程序的Timethreads圖
四、使用Thread-Specific Storage模式示例程序
1.示例程序類的一覽表
| TSLog.java | 創(chuàng)建日志的類(實例屬于各個線程所有) | 
| Log.java | 創(chuàng)建日志的類(分配各個線程) | 
| java.lang.ThreadLocal | 分配線程特有的存儲空間的類 | 
| ClientThread.java | 表示調(diào)用Log的線程的類 | 
| Main | 測試示例程序的類 | 
2.示例程序的類圖
3.TSLog類
package com.viagra.Thread_Specific_Storage_Pattern.Lesson2; import java.io.FileWriter; import java.io.IOException; import java.io.PrintWriter;public class TSLog {private PrintWriter writer = null;//初始化writer字段public TSLog(String filename) {try {writer = new PrintWriter(new FileWriter(filename));} catch (IOException e) {e.printStackTrace();}}//寫日志public void println(String s) {writer.println(s);}//關(guān)閉日志public void close() {writer.println("=== End of log ===");writer.close();} }4.Log類
package com.viagra.Thread_Specific_Storage_Pattern.Lesson2;public class Log {private static final ThreadLocal<TSLog> tslogCollection = new ThreadLocal<TSLog>();//寫日志public static void println(String s) {getTSLog().println(s);}//關(guān)閉日志public static void close() {getTSLog().close();}//獲取線程特有的日志private static TSLog getTSLog() {TSLog tsLog = tslogCollection.get();//如果該線程是第一次調(diào)用本方法,就新生成并注冊一個日志if (tsLog == null) {tsLog = new TSLog(Thread.currentThread().getName() + "-log.txt");tslogCollection.set(tsLog);}return tsLog;} }5.ClientThread類
package com.viagra.Thread_Specific_Storage_Pattern.Lesson2;/*** @Auther: viagra* @Date: 2019/11/19 20:22* @Description:*/ public class ClientThread extends Thread {public ClientThread(String name) {super(name);}public void run() {System.out.println(getName() + " Begin");for (int i = 0; i < 10; i++) {Log.println(getName() + " i = " + i);try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}}Log.close();System.out.println(getName() + " End");} }6.Main類
package com.viagra.Thread_Specific_Storage_Pattern.Lesson2;/*** @Auther: viagra* @Date: 2019/11/19 20:27* @Description:*/ public class Main {public static void main(String[] args) {new ClientThread("Steve Nash").start();new ClientThread("Michael Jordan").start();new ClientThread("Ronaldo").start();} }7.運行結(jié)果
Steve Nash Begin Michael Jordan Begin Ronaldo Begin Michael Jordan End Steve Nash End Ronaldo End //這里分別創(chuàng)建了Michael Jordan-log.txt、Ronaldo-log.txt、Steve Nash-log.txt8.生成文件內(nèi)容
//如Michael Jordan-log.txt Michael Jordan i = 0 Michael Jordan i = 1 Michael Jordan i = 2 Michael Jordan i = 3 Michael Jordan i = 4 Michael Jordan i = 5 Michael Jordan i = 6 Michael Jordan i = 7 Michael Jordan i = 8 Michael Jordan i = 9 === End of log ===9.示例程序的Timethreads圖
五、Thread-Specific Storage模式中角色
1.Client(委托者)
Client角色將處理委托給TSObjectProxy角色,一個TSObjectProxy角色會被多個Client角色使用,是示例程序2中的ClientThread類。
2.TSObjectProxy(線程持有的對象的代理人)
TSObjectProxy角色會執(zhí)行多個Client角色委托給的處理。是示例程序2中的Log類。
3.TSObjectCollection(線程持有的對象的集合)
TSObjectCollection角色有一張Client角色與TSObject角色之間的對應表。是示例程序2中的java.lang.ThreadLocal類。
4.TSObject(線程持有的對象)
TSObject角色中保存著線程持有的信息,是示例程序2中的TSLog類。
5.Thread-Specific Storage模式的類圖
6.Thread-Specific Storage模式的時序圖
總結(jié)
以上是生活随笔為你收集整理的java多线程之Thread-Specific Storage模式的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: WPF基本控件的简介(二)
 - 下一篇: python利用四个坐标点对图片目标区域