深入探讨5种单例模式

文章目录

  • 一、对比总览
      • 详细解释
  • 二、代码
    • 1. 饿汉式
    • 2. 饱汉式
    • 3. 饱汉式-双检锁
    • 4. 静态内部类
    • 5. 枚举单例
  • 三、性能对比

一、对比总览

以下是不同单例模式实现方式的特性对比表格。表格从线程安全性、延迟加载、实现复杂度、反序列化安全性、防反射攻击性等多个方面进行考量。

特性饿汉式饱汉式饱汉式-双检锁静态内部类枚举单例(推荐)
线程安全性×
延迟加载××
实现复杂度×
反序列化安全性××××
防反射攻击性××××

详细解释

  1. 线程安全性

    • 饿汉式:类加载时即创建实例(因为instance是static),线程安全。
    • 饱汉式:未使用同步机制,线程不安全。
    • 饱汉式-双检锁:使用同步块和双重检查锁,线程安全。
    • 静态内部类:通过类加载机制,线程安全。
    • 枚举单例:JVM确保线程安全。
  2. 延迟加载

    • 饿汉式:类加载时即创建实例,不具备延迟加载。
    • 饱汉式:实例在首次使用时创建,具备延迟加载。
    • 饱汉式-双检锁:实例在首次使用时创建,具备延迟加载。
    • 静态内部类:实例在首次使用时创建(因为静态内部类只有在使用时才会加载),具备延迟加载。
    • 枚举单例:类加载时即创建实例,不具备延迟加载。
  3. 实现复杂度

    • 饿汉式:实现简单。
    • 饱汉式:实现简单。
    • 饱汉式-双检锁:实现相对复杂。
    • 静态内部类:实现简单。
    • 枚举单例:实现简单。
  4. 反序列化安全性

    • 饿汉式饱汉式饱汉式-双检锁静态内部类:需要实现 readResolve 方法以防止反序列化创建新实例。
    • 枚举单例:天然防止反序列化创建新实例,JVM保证。
  5. 防反射攻击性

    • 饿汉式饱汉式饱汉式-双检锁静态内部类:可能通过反射创建新实例。
    • 枚举单例:防止反射攻击,创建新实例时抛出 IllegalArgumentException

二、代码

1. 饿汉式

public class OrderManager1 {@Getter@Setterprivate Map<String, TradeOrder> orders = new HashMap<>();@Getterprivate static final OrderManager1 instance = new OrderManager1();/*** 添加订单** @param order 顺序*/public void addOrder(TradeOrder order) {orders.put(order.getId(), order);}/*** 获取订单** @param orderId 订单id* @return {@link TradeOrder}*/public TradeOrder getOrder(String orderId) {return orders.get(orderId);}
}

2. 饱汉式

public class OrderManager2 {@Getter@Setterprivate Map<String, TradeOrder> orders = new HashMap<>();private static OrderManager2 instance;public static OrderManager2 getInstance(){if (instance == null){instance = new OrderManager2();}return instance;}/*** 添加订单** @param order 顺序*/public void addOrder(TradeOrder order) {orders.put(order.getId(), order);}/*** 获取订单** @param orderId 订单id* @return {@link TradeOrder}*/public TradeOrder getOrder(String orderId) {return orders.get(orderId);}
}

3. 饱汉式-双检锁

public class OrderManager3 {@Getter@Setterprivate Map<String, TradeOrder> orders = new HashMap<>();private static OrderManager3 instance;public static OrderManager3 getInstance(){if (instance == null){synchronized (OrderManager3.class){if (instance == null){instance = new OrderManager3();}}instance = new OrderManager3();}return instance;}/*** 添加订单** @param order 顺序*/public void addOrder(TradeOrder order) {orders.put(order.getId(), order);}/*** 获取订单** @param orderId 订单id* @return {@link TradeOrder}*/public TradeOrder getOrder(String orderId) {return orders.get(orderId);}
}

4. 静态内部类

public class OrderManager4 {@Getter@Setterprivate Map<String, TradeOrder> orders = new HashMap<>();private static class SingletonHelper{private static final OrderManager4 INSTANCE = new OrderManager4();}public static OrderManager4 getInstance(){return SingletonHelper.INSTANCE;}/*** 添加订单** @param order 顺序*/public void addOrder(TradeOrder order) {orders.put(order.getId(), order);}/*** 获取订单** @param orderId 订单id* @return {@link TradeOrder}*/public TradeOrder getOrder(String orderId) {return orders.get(orderId);}
}

5. 枚举单例

public enum OrderManager5 {INSTANCE;@Getter@Setterprivate Map<String, TradeOrder> orders = new HashMap<>();/*** 添加订单** @param order 顺序*/public void addOrder(TradeOrder order) {orders.put(order.getId(), order);}/*** 获取订单** @param orderId 订单id* @return {@link TradeOrder}*/public TradeOrder getOrder(String orderId) {return orders.get(orderId);}
}

三、性能对比

package org.dragon.singleton;import lombok.extern.slf4j.Slf4j;import java.util.*;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;@Slf4j
public class SingletonPerformanceTest {static long timeout = 20; // 超时时间,单位为秒static int testIterations = 10_000_000; // 测试次数static int threadCount = 1000; // 并发线程数static Map<String, HashMap<String, Long>> result = new HashMap<>();public static void main(String[] args) {/** 多次调用,结果是最后一次调用存入。为什么多次调用,因为单次test不准确,总是靠前的OrderManager跑的快,可能是因为Java某些机制导致的* 所以多次调用,逐渐平稳。* */firstCreationTest();mulAccessTest();mulAccessTest();mulAccessTest();ConcurrentAccessTest();ConcurrentAccessTest();printRes();ConcurrentAccessTest();printRes();ConcurrentAccessTest();printRes();}/*** 打印结果*/private static void printRes(){ArrayList<String> names = new ArrayList<>();names.add(OrderManager1.class.getSimpleName());names.add(OrderManager2.class.getSimpleName());names.add(OrderManager3.class.getSimpleName());names.add(OrderManager4.class.getSimpleName());names.add(OrderManager5.class.getSimpleName());// 表头System.out.printf("%-20s%-20s%-25s%-25s%-20s%n", "Singleton Type", "First Creation (ms)", "Multiple Access (ms)", "Concurrent Access (ms)", "Memory Used (MB)");System.out.println("---------------------------------------------------------------------------------------------------------------");for (String name : names) {// 打印结果,转换时间为毫秒System.out.printf("%-20s%-20.3f%-25.3f%-25.3f%-20.3f%n", name, result.get(name).get("firstCreation") / 1_000_000.0, result.get(name).get("mulAccess") / 1_000_000.0, result.get(name).get("ConcurrentAccess") / 1_000_000.0, 0 / (1024.0 * 1024.0));}}/*** 首次创建测试*/private static void firstCreationTest(){List<Runnable> tests = new ArrayList<>();tests.add(()->firstCreation(OrderManager1::getInstance));tests.add(()->firstCreation(OrderManager2::getInstance));tests.add(()->firstCreation(OrderManager3::getInstance));tests.add(()->firstCreation(OrderManager4::getInstance));tests.add(()->firstCreation(() -> OrderManager5.INSTANCE));// 随机化测试顺序Collections.shuffle(tests);//runfor (Runnable test : tests) {test.run();log.info("Complete one test");try {Thread.sleep(200);} catch (InterruptedException e) {throw new RuntimeException(e);}}}/*** 多次访问测试*/private static void mulAccessTest(){List<Runnable> tests = new ArrayList<>();tests.add(()->mulAccess(OrderManager1::getInstance, testIterations));tests.add(()->mulAccess(OrderManager2::getInstance, testIterations));tests.add(()->mulAccess(OrderManager3::getInstance, testIterations));tests.add(()->mulAccess(OrderManager4::getInstance, testIterations));tests.add(()->mulAccess(() -> OrderManager5.INSTANCE, testIterations));// 随机化测试顺序Collections.shuffle(tests);//runfor (Runnable test : tests) {test.run();log.info("Complete one test");try {Thread.sleep(200);} catch (InterruptedException e) {throw new RuntimeException(e);}}}/*** 多线程访问测试*/private static void ConcurrentAccessTest(){List<Runnable> tests = new ArrayList<>();tests.add(()->ConcurrentAccess(OrderManager1::getInstance, testIterations, threadCount));tests.add(()->ConcurrentAccess(OrderManager2::getInstance, testIterations, threadCount));tests.add(()->ConcurrentAccess(OrderManager3::getInstance, testIterations, threadCount));tests.add(()->ConcurrentAccess(OrderManager4::getInstance, testIterations, threadCount));tests.add(()->ConcurrentAccess(() -> OrderManager5.INSTANCE, testIterations, threadCount));// 随机化测试顺序Collections.shuffle(tests);//runfor (Runnable test : tests) {test.run();log.info("Complete one test");try {Thread.sleep(200);} catch (InterruptedException e) {throw new RuntimeException(e);}}}/*** 首次创建** @param singletonSupplier 单一供应商* @return long ns*/private static <T> long firstCreation(Supplier<T> singletonSupplier){// 测试首次创建时间long startTime = System.nanoTime();T instance = singletonSupplier.get();long endTime = System.nanoTime();long resTime = endTime - startTime;//save resString simpleName = instance.getClass().getSimpleName();HashMap<String, Long> resMap = result.computeIfAbsent(simpleName, k->new HashMap<>());resMap.put("firstCreation", resTime);return resTime;}/*** 多次访问** @param singletonSupplier 单一供应商* @param iterations        迭代* @return long ns*/private static <T> long mulAccess(Supplier<T> singletonSupplier, int iterations){//预热for (int i = 0; i < 100_000; i++) {T instance = singletonSupplier.get();}//计算long startTime = System.nanoTime();for (int i = 0; i < iterations; i++) {T instance = singletonSupplier.get();}long endTime = System.nanoTime();long resTime = endTime - startTime;//save resString simpleName = singletonSupplier.get().getClass().getSimpleName();HashMap<String, Long> resMap = result.computeIfAbsent(simpleName, k->new HashMap<>());resMap.put("mulAccess", resTime);return resTime;}/*** 并发访问** @param singletonSupplier 单一供应商* @param iterations        迭代* @param threadCount       线程数* @return long ns*/private static <T> long ConcurrentAccess(Supplier<T> singletonSupplier, int iterations, int threadCount){ExecutorService executorService = Executors.newFixedThreadPool(100);//预热CountDownLatch latch1 = new CountDownLatch(100);for (int i = 0; i < threadCount; i++) {executorService.submit(() -> {for (int j = 0; j < 100_000; j++) {T instance = singletonSupplier.get();}latch1.countDown();});}try {boolean completed = latch1.await(timeout, TimeUnit.SECONDS);if (!completed) {System.out.println("Concurrent access test for 预热" + singletonSupplier.get().getClass().getSimpleName() + " timed out!");}} catch (InterruptedException e) {e.printStackTrace();}//计算CountDownLatch latch2 = new CountDownLatch(threadCount);long startTime = System.nanoTime();for (int i = 0; i < threadCount; i++) {executorService.submit(() -> {for (int j = 0; j < iterations; j++) {T instance = singletonSupplier.get();}latch2.countDown();});}try {boolean completed = latch2.await(timeout, TimeUnit.SECONDS);if (!completed) {System.out.println("Concurrent access test for " + singletonSupplier.getClass().getSimpleName() + " timed out!");}} catch (InterruptedException e) {e.printStackTrace();}long endTime = System.nanoTime();long concurrentAccessTime = endTime - startTime;executorService.shutdown();//save resString simpleName = singletonSupplier.get().getClass().getSimpleName();HashMap<String, Long> resMap = result.computeIfAbsent(simpleName, k->new HashMap<>());resMap.put("ConcurrentAccess", concurrentAccessTime);return concurrentAccessTime;}
}

结果输出如下

[17:15:54.519] [INFO ] org.dragon.singleton.SingletonPerformanceTest 73 firstCreationTest - Complete one test
[17:15:54.730] [INFO ] org.dragon.singleton.SingletonPerformanceTest 73 firstCreationTest - Complete one test
[17:15:54.936] [INFO ] org.dragon.singleton.SingletonPerformanceTest 73 firstCreationTest - Complete one test
[17:15:55.141] [INFO ] org.dragon.singleton.SingletonPerformanceTest 73 firstCreationTest - Complete one test
[17:15:55.347] [INFO ] org.dragon.singleton.SingletonPerformanceTest 73 firstCreationTest - Complete one test
[17:15:55.554] [INFO ] org.dragon.singleton.SingletonPerformanceTest 97 mulAccessTest - Complete one test
[17:15:55.782] [INFO ] org.dragon.singleton.SingletonPerformanceTest 97 mulAccessTest - Complete one test
[17:15:56.007] [INFO ] org.dragon.singleton.SingletonPerformanceTest 97 mulAccessTest - Complete one test
[17:15:56.227] [INFO ] org.dragon.singleton.SingletonPerformanceTest 97 mulAccessTest - Complete one test
[17:15:56.445] [INFO ] org.dragon.singleton.SingletonPerformanceTest 97 mulAccessTest - Complete one test
[17:15:56.669] [INFO ] org.dragon.singleton.SingletonPerformanceTest 97 mulAccessTest - Complete one test
[17:15:56.906] [INFO ] org.dragon.singleton.SingletonPerformanceTest 97 mulAccessTest - Complete one test
[17:15:57.146] [INFO ] org.dragon.singleton.SingletonPerformanceTest 97 mulAccessTest - Complete one test
[17:15:57.376] [INFO ] org.dragon.singleton.SingletonPerformanceTest 97 mulAccessTest - Complete one test
[17:15:57.598] [INFO ] org.dragon.singleton.SingletonPerformanceTest 97 mulAccessTest - Complete one test
[17:15:57.818] [INFO ] org.dragon.singleton.SingletonPerformanceTest 97 mulAccessTest - Complete one test
[17:15:58.054] [INFO ] org.dragon.singleton.SingletonPerformanceTest 97 mulAccessTest - Complete one test
[17:15:58.276] [INFO ] org.dragon.singleton.SingletonPerformanceTest 97 mulAccessTest - Complete one test
[17:15:58.495] [INFO ] org.dragon.singleton.SingletonPerformanceTest 97 mulAccessTest - Complete one test
[17:15:58.716] [INFO ] org.dragon.singleton.SingletonPerformanceTest 97 mulAccessTest - Complete one test
[17:15:59.430] [INFO ] org.dragon.singleton.SingletonPerformanceTest 121 ConcurrentAccessTest - Complete one test
[17:15:59.658] [INFO ] org.dragon.singleton.SingletonPerformanceTest 121 ConcurrentAccessTest - Complete one test
[17:16:02.737] [INFO ] org.dragon.singleton.SingletonPerformanceTest 121 ConcurrentAccessTest - Complete one test
[17:16:08.533] [INFO ] org.dragon.singleton.SingletonPerformanceTest 121 ConcurrentAccessTest - Complete one test
[17:16:13.700] [INFO ] org.dragon.singleton.SingletonPerformanceTest 121 ConcurrentAccessTest - Complete one test
[17:16:19.432] [INFO ] org.dragon.singleton.SingletonPerformanceTest 121 ConcurrentAccessTest - Complete one test
[17:16:24.632] [INFO ] org.dragon.singleton.SingletonPerformanceTest 121 ConcurrentAccessTest - Complete one test
[17:16:30.366] [INFO ] org.dragon.singleton.SingletonPerformanceTest 121 ConcurrentAccessTest - Complete one test
[17:16:35.516] [INFO ] org.dragon.singleton.SingletonPerformanceTest 121 ConcurrentAccessTest - Complete one test
[17:16:40.431] [INFO ] org.dragon.singleton.SingletonPerformanceTest 121 ConcurrentAccessTest - Complete one test
Singleton Type      First Creation (ms) Multiple Access (ms)     Concurrent Access (ms)   Memory Used (MB)    
---------------------------------------------------------------------------------------------------------------
OrderManager1       0.010               16.848                   4928.236                 0.000               
OrderManager2       0.010               18.592                   5504.781                 0.000               
OrderManager3       0.009               19.127                   5513.309                 0.000               
OrderManager4       0.241               18.772                   4920.940                 0.000               
OrderManager5       0.117               16.637                   4704.835                 0.000               
[17:16:45.002] [INFO ] org.dragon.singleton.SingletonPerformanceTest 121 ConcurrentAccessTest - Complete one test
[17:16:48.982] [INFO ] org.dragon.singleton.SingletonPerformanceTest 121 ConcurrentAccessTest - Complete one test
[17:16:52.778] [INFO ] org.dragon.singleton.SingletonPerformanceTest 121 ConcurrentAccessTest - Complete one test
[17:16:57.834] [INFO ] org.dragon.singleton.SingletonPerformanceTest 121 ConcurrentAccessTest - Complete one test
[17:17:02.298] [INFO ] org.dragon.singleton.SingletonPerformanceTest 121 ConcurrentAccessTest - Complete one test
Singleton Type      First Creation (ms) Multiple Access (ms)     Concurrent Access (ms)   Memory Used (MB)    
---------------------------------------------------------------------------------------------------------------
OrderManager1       0.010               16.848                   4217.333                 0.000               
OrderManager2       0.010               18.592                   4340.869                 0.000               
OrderManager3       0.009               19.127                   4824.581                 0.000               
OrderManager4       0.241               18.772                   3743.032                 0.000               
OrderManager5       0.117               16.637                   3558.995                 0.000               
[17:17:06.778] [INFO ] org.dragon.singleton.SingletonPerformanceTest 121 ConcurrentAccessTest - Complete one test
[17:17:11.231] [INFO ] org.dragon.singleton.SingletonPerformanceTest 121 ConcurrentAccessTest - Complete one test
[17:17:15.733] [INFO ] org.dragon.singleton.SingletonPerformanceTest 121 ConcurrentAccessTest - Complete one test
[17:17:20.812] [INFO ] org.dragon.singleton.SingletonPerformanceTest 121 ConcurrentAccessTest - Complete one test
[17:17:25.837] [INFO ] org.dragon.singleton.SingletonPerformanceTest 121 ConcurrentAccessTest - Complete one test
Singleton Type      First Creation (ms) Multiple Access (ms)     Concurrent Access (ms)   Memory Used (MB)    
---------------------------------------------------------------------------------------------------------------
OrderManager1       0.010               16.848                   4281.649                 0.000               
OrderManager2       0.010               18.592                   4849.279                 0.000               
OrderManager3       0.009               19.127                   4782.224                 0.000               
OrderManager4       0.241               18.772                   4267.228                 0.000               
OrderManager5       0.117               16.637                   4233.907                 0.000               进程已结束,退出代码为 0

可以去多跑几次,基本上最后一种枚举单例,性能属于最好的一批。并且也最安全。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/345817.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

淘宝扭蛋机小程序,扭蛋市场创新模式

扭蛋机作为潮玩市场的娱乐消费方式&#xff0c;成为了当下消费者的新宠。扭蛋机凭借自身性价比高、商品多样、惊喜性等特点&#xff0c;吸引了各个年龄层的消费者&#xff0c;不仅年轻人喜欢&#xff0c;不少小学生和老年人也非常喜欢&#xff0c;扭蛋机市场迎来了快速发展期。…

MySQL: 表的增删改查(基础)

文章目录 1. 注释2. 新增(Create)3. 查询(Retrieve)3.1 全列查询3.2 指定列查询3.3 查询字段为表达式3.4 别名3.5 去重: distinct3.6 排序: order by3.7条件查询3.8 分页查询 4. 修改 (update)5. 删除(delete)6. 内容重点总结 1. 注释 注释&#xff1a;在SQL中可以使用“–空格…

Spring Boot 集成 zxing 生成条形码与二维码

前面我们知道了怎么通过 使用 zxing 生成二维码以及条形码&#xff0c; 由于我们现在都是 web 端的项目了&#xff0c;那么我们看下怎么使用 Spring Boot 集成然后返回给前端展示&#xff1a; 工程源码 对应的工程源码我放到了这里&#xff1a;github源码路径&#xff0c;点击…

大模型Prompt-Tuning技术进阶

LLM的Prompt-Tuning主流方法 面向超大规模模型的Prompt-Tuning 近两年来&#xff0c;随之Prompt-Tuning技术的发展&#xff0c;有诸多工作发现&#xff0c;对于超过10亿参数量的模型来说&#xff0c;Prompt-Tuning所带来的增益远远高于标准的Fine-tuning&#xff0c;小样本甚至…

基于STM32的各种数学函数优化计算方法(代码开源)

前言&#xff1a;本文为手把手教学 STM32 的数学计算公式优化方法的教程&#xff0c;本教程的 MCU 使用 STM32F103ZET6 。本篇博客将使用非传统数学库计算手段进行各种数学函数的计算&#xff0c;优化的数学计算包括&#xff1a;sin()、cos()、arctan()、arcsin() 与 1/sqrt()。…

Python魔法之旅专栏(导航)

目录 推荐阅读 1、Python筑基之旅 2、Python函数之旅 3、Python算法之旅 4、博客个人主页 首先&#xff0c;感谢老铁们一直以来对我的支持与厚爱&#xff0c;让我能坚持把Python魔法方法专栏更新完毕&#xff01; 其次&#xff0c;为了方便大家查阅&#xff0c;我将此专栏…

NetSuite精益实施 之 系统切换作业标准化

这个题目为近日所思&#xff0c;一直没有落笔。今天是端午假日&#xff0c;得空卸货。 标准化是精益实施的三个基础之一&#xff0c;在我们的项目实践中没有须臾忘记。在此我们不再赘述标准化为啥这么重要&#xff0c;更多来分享如何标准化。 在项目实施的各阶段中&#xff0…

冯喜运:6.10周一黄金原油行情趋势分析及独家操作建议

【黄金消息面分析】&#xff1a;上周全球金融市场惊现戏剧性大逆转&#xff0c;美国多项经济数据证实劳动力市场降温&#xff0c;9月降息重返视野令全球风险情绪几乎陷入狂热状态&#xff0c;全球股市接连创新高&#xff0c;但上周五意外“爆表”的非农令市场惊现大逆转&#x…

【LeetCode】39.组合总和

组合总和 题目描述&#xff1a; 给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target &#xff0c;找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 &#xff0c;并以列表形式返回。你可以按 任意顺序 返回这些组合。 candidates 中的 同一个…

c#未能加载基类System错误 这台计算机上缺少此项目引用的 NuGet 程序包

拷贝代码到另一台计算机运行&#xff0c;打开Form1.cs报错 首先确认package的框架 如果是472&#xff0c;则更换472的框架 打开项目->xx属性&#xff0c;进行修改 如果框架正确&#xff0c;就是未识别到程序包 可以参考&#xff1a; https://www.cnblogs.com/txwtech/p/1…

深入ES6:解锁 JavaScript 类与继承的高级玩法

个人主页&#xff1a;学习前端的小z 个人专栏&#xff1a;JavaScript 精粹 本专栏旨在分享记录每日学习的前端知识和学习笔记的归纳总结&#xff0c;欢迎大家在评论区交流讨论&#xff01; ES5、ES6介绍 文章目录 &#x1f4af;Class&#x1f35f;1 类的由来&#x1f35f;2 co…

一、Socket创建和连接

C网络编程&#xff08;asio&#xff09; 文章目录 C网络编程&#xff08;asio&#xff09;1、Asio概述2、网络编程基本流程2、创建socket3、创建监听socket4、绑定accpet监听套接字5、连接指定的端点6、服务器接收连接 点击查看代码 1、Asio概述 ​ Asio起源于Boost库&#xf…

Kafka 架构

1 整体架构 1.1 Zookeeper Zookeeper 是一个分布式协调服务&#xff0c;用于管理 Kafka 的元数据。它负责维护 Kafka 集群的配置信息、Broker 列表和分区的 Leader 信息。 Zookeeper 确保了 Kafka 集群的高可用性和可靠性。 但 Zookeeper 已经成为 Kafka 性能瓶颈&#xff0c;…

【Vue】获取模块内的actions方法

目标&#xff1a; 掌握模块中 action 的调用语法 (同理 - 直接类比 mutation 即可) 注意&#xff1a; 默认模块中的 mutation 和 actions 会被挂载到全局&#xff0c;需要开启命名空间&#xff0c;才会挂载到子模块。 调用语法&#xff1a; 直接通过 store 调用 $store.di…

【Linux多线程】线程的终止、等待和分离

文章目录 线程终止正常退出return 退出pthread_exit函数终止线程 pthread_cancel强制终止线程进程终止 线程等待为什么需要等待线程&#xff1f;pthread_join函数 分离线程pthread_detach函数 线程终止 下面给出终止线程的三种方式&#xff1a; 正常退出&#xff1a; 线程执行…

【深度学习】PuLID: Pure and Lightning ID Customization via Contrastive Alignment

论文&#xff1a;https://arxiv.org/abs/2404.16022 代码&#xff1a;https://github.com/ToTheBeginning/PuLID 文章目录 AbstractIntroductionRelated WorkMethods Abstract 我们提出了一种新颖的、无需调整的文本生成图像ID定制方法——Pure and Lightning ID customizatio…

机器学习笔记 - LoRA:大型语言模型的低秩适应

一、简述 1、模型微调 随着大型语言模型 (LLM) 的规模增加到数千亿,对这些模型进行微调成为一项挑战。传统上,要微调模型,我们需要更新所有模型参数。这也称为完全微调 (FFT) 。下图详细概述了此方法的工作原理。 完全微调FFT 的计算成本和资源需求很大,因为更新每…

Vue TypeScript 实战:掌握静态类型编程

title: Vue TypeScript 实战&#xff1a;掌握静态类型编程 date: 2024/6/10 updated: 2024/6/10 excerpt: 这篇文章介绍了如何在TypeScript环境下为Vue.js应用搭建项目结构&#xff0c;包括初始化配置、创建Vue组件、实现状态管理利用Vuex、配置路由以及性能优化的方法&#x…

拐点已至:企业如何借助AI重塑增长?

2024年的激进增长与AI数智化创新并行&#xff0c;传统策略的功效已经减弱。在这篇文章中&#xff0c;我们将展望并深度探索2024年的6大创新增长策略&#xff0c;包括AI驱动的实验&#xff0c;产品再造&#xff0c;超个性化&#xff0c;自动化运营&#xff0c;短视频和KOL营销等…

Kimichat使用案例010:快速识别出图片中的表格保存到Excel

文章目录 一、介绍二、图片信息三、输入内容四、输出内容五、markdown提示词六、markdown输出一、介绍 如果有一张图片格式的表格,想要快速复制到Excel表格中,那么一般要借助于OCR工具。之前试过不少在线OCR工具,识别效果差强人意。其实,kimichat就可以非常好的完成这个任务…