设为首页 加入收藏

TOP

Java多线程(4):ThreadLocal(一)
2023-07-25 21:28:38 】 浏览:43
Tags:Java ThreadLocal

您好,我是湘王,这是我的博客园,欢迎您来,欢迎您再来~

 

为了提高CPU的利用率,工程师们创造了多线程。但是线程们说:要有光!(为了减少线程创建(T1启动)和销毁(T3切换)的时间),于是工程师们又接着创造了线程池ThreadPool。就这样就可以了吗——不,工程师们并不满足于此,他们不把自己创造出来的线程给扒个底朝天决不罢手。

有了线程关键字解决线程安全问题,有了线程池解决效率问题,那还有什么问题是可以需要被解决的呢——还真被这帮疯子攻城狮给找到了!

当多个线程共享同一个资源的时候,为了保证线程安全,有时不得不给资源加锁,例如使用Synchronized关键字实现同步锁。这本质上其实是一种时间换空间的搞法——用单一资源让不同的线程依次访问,从而实现内容安全可控。就像这样:

 

 

 

但是,可以不可以反过来,将资源拷贝成多份副本的形式来同时访问,达到一种空间换时间的效果呢?当然可以,就像这样:

 

 

 

而这,就是ThreadLocal最核心的思想。

 

但这种方式在很多应用级开发的场景中用得真心不多,而且有些公司还禁止使用ThreadLocal,因为它搞不好还会带来一些负面影响。

其实,从拷贝若干副本这种功能来看,ThreadLocal是实现了在线程内部存储数据的能力的,而且相互之间还能通信。就像这样:

 

 

 

还是以代码的形式来解读一下ThreadLocal。有一个资源类Resource:

/**
 * 资源类
 *
 * @author 湘王
 */
public class Resource {
    private String name;
    private String value;

    public Resource(String name, String value) {
        super();
        this.name = name;
        this.value = value;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }
}

 

分别有ResuorceUtils1、ResuorceUtils2ResuorceUtils3分别以不同的方式来连接资源,那么看看效率如何。

/**
 * 连接资源工具类,通过静态方式获得连接
 *
 * @author 湘王
 */
public class ResourceUtils1 {
    // 定义一个静态连接资源
    private static Resource resource = null;
    // 获取连接资源
    public static Resource getResource() {
        if(resource == null) {
            resource = new Resource("xiangwang", "123456");
        }
        return resource;
    }

    // 关闭连接资源
    public static void closeResource() {
        if(resource != null) {
            resource = null;
        }
    }
}



/**
 * 连接资源工具类,通过实例化方式获得连接
 *
 * @author 湘王
 */
public class ResourceUtils2 {
    // 定义一个连接资源
    private Resource resource = null;
    // 获取连接资源
    public Resource getResource() {
        if(resource == null) {
            resource = new Resource("xiangwang", "123456");
        }
        return resource;
    }

    // 关闭连接资源
    public void closeResource() {
        if(resource != null) {
            resource = null;
        }
    }
}



/**
 * 连接资源工具类,通过线程中的static Connection的副本方式获得连接
 *
 * @author 湘王
 */
public class ResourceUtils3 {
    // 定义一个静态连接资源
    private static Resource resource = null;
    private static ThreadLocal<Resource> resourceContainer = new ThreadLocal<Resource>();
    // 获取连接资源
    public static Resource getResource() {
        synchronized(ResourceManager.class) {
            resource = resourceContainer.get();
            if(resource == null) {
                resource = new Resource("xiangwang", "123456");
                resourceContainer.set(resource);
            }
            return resource;
        }
    }

    // 关闭连接资源
    public static void closeResource() {
        if(resource != null) {
            resource = null;
            resourceContainer.remove();
        }
    }
}



/**
 * 连接资源管理类
 *
 * @author 湘王
 */
public class ResourceManager {
    public void insert() {
        // 获取连接
        // System.out.println("Dao.insert()-->" + Thread.currentThread().getName() + ResourceUtils1.getResource());
        // Resource resource = new ResourceUtils2().getResource();
        Resource resource = ResourceUtils3.getResource();
        System.out.println("Dao.insert()-->" + Thread.currentThread().getName() + resource);
    }

    public void delete() {
        // 获取连接
        // System.out.println("Dao.delete()-->" + Thread.currentThread().getName() + ResourceUtils1.getResource());
        // Resource resource = new ResourceUtils2().getResource();
        Resource resourc
首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Java-方法重载 下一篇Java 网络编程 —— ServerSocket..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目