当前位置: 首页 > news >正文

如何用dreamweaver做网站现在百度推广有用吗

如何用dreamweaver做网站,现在百度推广有用吗,做系统和做网站的区别,上海网站建设报价方案ThreadLocal 是一个存储线程本地副本的工具类。 要保证线程安全,不一定非要进行同步。同步只是保证共享数据争用时的正确性,如果一个方法本来就不涉及共享数据,那么自然无须同步。 Java 中的 无同步方案 有: 可重入代码 - 也叫…

ThreadLocal 是一个存储线程本地副本的工具类

要保证线程安全,不一定非要进行同步。同步只是保证共享数据争用时的正确性,如果一个方法本来就不涉及共享数据,那么自然无须同步。

Java 中的 无同步方案 有:

  • 可重入代码 - 也叫纯代码。如果一个方法,它的 返回结果是可以预测的,即只要输入了相同的数据,就能返回相同的结果,那它就满足可重入性,当然也是线程安全的。
  • 线程本地存储 - 使用 ThreadLocal 为共享变量在每个线程中都创建了一个本地副本,这个副本只能被当前线程访问,其他线程无法访问,那么自然是线程安全的。

1.1. ThreadLocal 的应用

ThreadLocal 的方法:

public class ThreadLocal<T> {public T get() {}public void set(T value) {}public void remove() {}public static <S> ThreadLocal<S> withInitial(Supplier<? extends S> supplier) {}
}

说明:

  • get - 用于获取 ThreadLocal 在当前线程中保存的变量副本。
  • set - 用于设置当前线程中变量的副本。
  • remove - 用于删除当前线程中变量的副本。如果此线程局部变量随后被当前线程读取,则其值将通过调用其 initialValue 方法重新初始化,除非其值由中间线程中的当前线程设置。 这可能会导致当前线程中多次调用 initialValue 方法。
  • initialValue - 为 ThreadLocal 设置默认的 get 初始值,需要重写 initialValue 方法 。

ThreadLocal 常用于防止对可变的单例(Singleton)变量或全局变量进行共享。典型应用场景有:管理数据库连接、Session。

【示例】数据库连接

private static ThreadLocal<Connection> connectionHolder = new ThreadLocal<Connection>() {@Overridepublic Connection initialValue() {return DriverManager.getConnection(DB_URL);}
};public static Connection getConnection() {return connectionHolder.get();
}

【示例】Session 管理

private static final ThreadLocal<Session> sessionHolder = new ThreadLocal<>();public static Session getSession() {Session session = (Session) sessionHolder.get();try {if (session == null) {session = createSession();sessionHolder.set(session);}} catch (Exception e) {e.printStackTrace();}return session;
}

【示例】完整使用 ThreadLocal 示例

public class ThreadLocalDemo {private static ThreadLocal<Integer> threadLocal = new ThreadLocal<Integer>() {@Overrideprotected Integer initialValue() {return 0;}};public static void main(String[] args) {ExecutorService executorService = Executors.newFixedThreadPool(10);for (int i = 0; i < 10; i++) {executorService.execute(new MyThread());}executorService.shutdown();}static class MyThread implements Runnable {@Overridepublic void run() {int count = threadLocal.get();for (int i = 0; i < 10; i++) {try {count++;Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}}threadLocal.set(count);threadLocal.remove();System.out.println(Thread.currentThread().getName() + " : " + count);}}}

全部输出 count = 10

1.2. ThreadLocal 的原理

存储结构

Thread 类中维护着一个 ThreadLocal.ThreadLocalMap 类型的成员 threadLocals。这个成员就是用来存储当前线程独占的变量副本。

ThreadLocalMapThreadLocal 的内部类,它维护着一个 Entry 数组,Entry 继承了 WeakReference ,所以是弱引用。 Entry 用于保存键值对,其中:

  • keyThreadLocal 对象;
  • value 是传递进来的对象(变量副本)。
public class Thread implements Runnable {// ...ThreadLocal.ThreadLocalMap threadLocals = null;// ...
}static class ThreadLocalMap {// ...static class Entry extends WeakReference<ThreadLocal<?>> {/** The value associated with this ThreadLocal. */Object value;Entry(ThreadLocal<?> k, Object v) {super(k);value = v;}}// ...
}

如何解决 Hash 冲突

ThreadLocalMap 虽然是类似 Map 结构的数据结构,但它并没有实现 Map 接口。它不支持 Map 接口中的 next 方法,这意味着 ThreadLocalMap 中解决 Hash 冲突的方式并非 拉链表 方式。

实际上,ThreadLocalMap 采用线性探测的方式来解决 Hash 冲突。所谓线性探测,就是根据初始 key 的 hashcode 值确定元素在 table 数组中的位置,如果发现这个位置上已经被其他的 key 值占用,则利用固定的算法寻找一定步长的下个位置,依次判断,直至找到能够存放的位置。

内存泄漏问题

ThreadLocalMapEntry 继承了 WeakReference,所以它的 key (ThreadLocal 对象)是弱引用,而 value (变量副本)是强引用

  • 如果 ThreadLocal 对象没有外部强引用来引用它,那么 ThreadLocal 对象会在下次 GC 时被回收。
  • 此时,Entry 中的 key 已经被回收,但是 value 由于是强引用不会被垃圾收集器回收。如果创建 ThreadLocal 的线程一直持续运行,那么 value 就会一直得不到回收,产生内存泄露

那么如何避免内存泄漏呢?方法就是:使用 ThreadLocalset 方法后,显示的调用 remove 方法

ThreadLocal<String> threadLocal = new ThreadLocal();
try {threadLocal.set("xxx");// ...
} finally {threadLocal.remove();
}

1.3. ThreadLocal 的误区

示例摘自:《Java 业务开发常见错误 100 例》(opens new window)

ThreadLocal 适用于变量在线程间隔离,而在方法或类间共享的场景。

前文提到,ThreadLocal 是线程隔离的,那么是不是使用 ThreadLocal 就一定高枕无忧呢?

ThreadLocal 错误案例

使用 Spring Boot 创建一个 Web 应用程序,使用 ThreadLocal 存放一个 Integer 的值,来暂且代表需要在线程中保存的用户信息,这个值初始是 null。

    private ThreadLocal<Integer> currentUser = ThreadLocal.withInitial(() -> null);@GetMapping("wrong")public Map<String, String> wrong(@RequestParam("id") Integer userId) {//设置用户信息之前先查询一次ThreadLocal中的用户信息String before = Thread.currentThread().getName() + ":" + currentUser.get();//设置用户信息到ThreadLocalcurrentUser.set(userId);//设置用户信息之后再查询一次ThreadLocal中的用户信息String after = Thread.currentThread().getName() + ":" + currentUser.get();//汇总输出两次查询结果Map<String, String> result = new HashMap<>();result.put("before", before);result.put("after", after);return result;}

【预期】从代码逻辑来看,我们预期第一次获取的值始终应该是 null。

【实际】

为了方便复现,将 Tomcat 工作线程设为 1:

server.tomcat.max-threads=1

当访问 id = 1 时,符合预期

当访问 id = 2 时,before 的应答不是 null,而是 1,不符合预期。

【分析】实际情况和预期存在偏差。Spring Boot 程序运行在 Tomcat 中,执行程序的线程是 Tomcat 的工作线程,而 Tomcat 的工作线程是基于线程池的。线程池会重用固定的几个线程,一旦线程重用,那么很可能首次从 ThreadLocal 获取的值是之前其他用户的请求遗留的值。这时,ThreadLocal 中的用户信息就是其他用户的信息

并不能认为没有显式开启多线程就不会有线程安全问题。使用类似 ThreadLocal 工具来存放一些数据时,需要特别注意在代码运行完后,显式地去清空设置的数据。

ThreadLocal 错误案例修正

    @GetMapping("right")public Map<String, String> right(@RequestParam("id") Integer userId) {String before = Thread.currentThread().getName() + ":" + currentUser.get();currentUser.set(userId);try {String after = Thread.currentThread().getName() + ":" + currentUser.get();Map<String, String> result = new HashMap<>();result.put("before", before);result.put("after", after);return result;} finally {//在finally代码块中删除ThreadLocal中的数据,确保数据不串currentUser.remove();}}

1.4. InheritableThreadLocal

InheritableThreadLocal 类是 ThreadLocal 类的子类。

ThreadLocal 中每个线程拥有它自己独占的数据。与 ThreadLocal 不同的是,InheritableThreadLocal 允许一个线程以及该线程创建的所有子线程都可以访问它保存的数据。

原理参考:Java 多线程:InheritableThreadLocal 实现原理

http://www.lbrq.cn/news/2722015.html

相关文章:

  • 如何安装wordpress博客东莞seo网站排名优化
  • 网络服务提供者知道或者应当知道网络seo工程师
  • 怎么看网站是什么程序做的百度认证中心
  • 网站建设软件公司西安疫情最新情况
  • 网络推广营销策略关键词怎么优化
  • 支付宝网站登录入口关键词seo是什么
  • 基层机构网站建设seo搜索排名影响因素主要有
  • python 做网站怎样安徽seo优化规则
  • 做虚拟主机网站合肥网站建设程序
  • 企业网站规划2023搜索最多的关键词
  • 网站上如何做天气插件百度站长工具添加不了站点
  • 个人电脑做网站服务器教程seo好学吗
  • 外包公司做网站图片哪里整的品牌建设的五个要素
  • 营销型网站建设的特点表现刷赞网站推广ks
  • 建设网站的公司兴田德润怎么联系网络营销策略包括哪四种
  • 做图片视频的网站有哪些问题吗汕头seo
  • 聊城哪儿做网站便宜广州seo和网络推广
  • 佛山做网站公司排名seo分析报告
  • 一站式营销平台重庆 seo
  • 小说网站的图片长图怎么做的跨境电商怎么开店铺
  • 酒厂网站源码餐饮培训
  • 建设一个网站可以放视频的多少钱数据分析培训
  • 临沂企业建站模板淘宝关键词排名查询工具
  • 网站维护费怎么做会计分录百度广告怎么投放
  • 做房地产网站广告销售客户管理软件哪个好用
  • 怎么制作网站教程下载搜易网服务介绍
  • 做3d人物模型素材下载网站信息流广告素材网站
  • 快站科技是什么互联网营销师考试内容
  • 里面云智能建站上海seo公司排名榜
  • 个人网站模板源码seo课程培训学校
  • 从前端框架到GIS开发系列课程(26)在mapbox中实现地球自转效果,并添加点击事件增强地图交互性
  • 前端动画库之gsap
  • Spring事物
  • 云原生俱乐部-k8s知识点归纳(3)
  • 关于C++的#include的超超超详细讲解
  • 一致性哈希Consistent Hashing