Fork me on GitHub

Thread-Specific Thread 模式

😃Thread-Specific Storage模式

Thread-Specific Storage模式是一种即使只有一个入口,也会内部为每个线程分配特有的空间的模式。

🎯 关于java.lang.ThreadLocal类

java.lang.ThreadLocal就是储物间

java.lang.ThreadLocal的实例当作集合可能更好理解,ThreadLocal的实例可以管理多个对象。

  • set方法
    ThreadLocal类的set方法用于将通过参数接受的实例与调用该方法的线程(当前线程)对应存储起来。
  • get方法
    ThreadLocal类的get方法用于获取与调用get方法的线程(当前线程)对应的实例。如果之前一次都还没有调用set方法。则返回null。

🎨示例程序

Main类

public class Main {
    public static void main(String[] args) {
        new ClientThread("Alice").start();
        new ClientThread("Bobby").start();
        new ClientThread("Chris").start();
    }
}

ClientThread类

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("i = " + i);
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
            }
        }
        Log.close();
        System.out.println(getName() + " END");
    }
}

Log类

public class Log {
    private static final ThreadLocal<TSLog> tsLogCollection = new ThreadLocal<TSLog>();

    // 写日志
    public static void println(String s) {
        getTSLog().println(s);
    }

    // 关闭日志
    public static void close() {
        getTSLog().close();
    }

    // 获取线程特有的日志
    private static TSLog getTSLog() {
        TSLog tsLog = tsLogCollection.get();

        // 如果该线程是第一次调用本方法,就新生成并注册一个日志
        if (tsLog == null) {
            tsLog = new TSLog(Thread.currentThread().getName() + "-log.txt");
            tsLogCollection.set(tsLog);
        }

        return tsLog;
    }
}

TSLog类

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);
    }

    // 关闭日志
    public void close() {
        writer.println("==== End of log ====");
        writer.close();
    }
}

🏄扩展思路

局部变量与java.lang.ThreadLocal类

局部变量在调用结束后就会消失,而ThreadLocal类则与方法调用无关,它是一个用于为线程分配特有的存储空间的类。

🐳延申阅读:基于角色与基于任务

基于角色的考虑方式

角色最伟大,即在表示线程的实例中保存进行工作的必要信息,一个线程会使用从其它线程接受到的信息来进行处理,改变自己的内部状态。这样的线程为 角色

基于任务的考虑方式

基于任务的考虑方式不在线程中保存信息。这些信息保存在线程之间交互的实例中。而且不仅仅是数据,连用于请求的方法都定义在其中,这种在线程间交互的实例称为消息、请求或是命令。
使用该模式的一个典型模式就是Worker Thread模式

class Task implements Ruunable {
    进行工作的信息
    public void run() {
        工作的内容
    }
}

📖参考书籍

  • 图解Java多线程设计模式

☀️诗与远方

若我们再次相遇,隔着悠长岁月,我将如何向你致意?
以沉默,以眼泪。

posted @ 2022-03-30 22:47  bugMaker-java  阅读(50)  评论(0编辑  收藏  举报