SimpleDateFormat非线程安全及解决方法

news2024/9/21 4:25:53

【RAEDME】

SimpleDateFormat非线程安全,即在多线程环境下解析字符串为日期对象,或格式化日期为字符串时,会抛出异常;当然,这是一个老生常谈的问题;

本文参考了已有 SimpleDateFormat的分析文章,做了总结,包括SimpleDateFormat报错代码,解决方法代码。

解决方法包括:

  • 方法1:SimpleDateFormat 使用单例;
  • 方法2:为解析方法加锁;避免多线程环境;
  • 方法3: 使用 ThreadLocal<SimpleDateFormat>; 每个线程获取的都是一个SimpleDateFormat单例,与方法1类似;
  • 方法4: 使用java8提供的 DateTimeFormatter (推荐);

参考资料:

Java's SimpleDateFormat is not thread-safe, Use carefully in multi-threaded environments | CalliCoderThe SimpleDateFormat class in Java is not thread-safe. You should either create separate instances of SimpleDateFormat for every thread, or synchronize concurrent access by multiple threads with a synchronized keyword or a lock.icon-default.png?t=N7T8https://www.callicoder.com/java-simpledateformat-thread-safety-issues/


【1】SimpleDateFormat在多线程环境下解析字符串报错

/**
 * @Description simple data format 解析失败
 * @author xiao tang
 * @version 1.0.0
 * @createTime 2023年10月05日
 */
public class SimpleDateFormatError {
    private static final SimpleDateFormat SIMPLE_DATE_FORMAT = new SimpleDateFormat("yyyyMMdd");

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        Callable<Date> task = () -> parse("20231005");
        // 线程池
        ExecutorService threadPool = Executors.newFixedThreadPool(10);
        ArrayList<Future<Date>> results = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            results.add(threadPool.submit(task));
        }
        // 获取异步执行结果
        for (Future<Date> result : results) {
            System.out.println(result.get());
        }
        threadPool.shutdown();
    }

    public static Date parse(String dateStr) {
        try {
            return SIMPLE_DATE_FORMAT.parse(dateStr);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

结果:

java.lang.NumberFormatException: multiple points
	at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1890)
	at sun.misc.FloatingDecimal.parseDouble(FloatingDecimal.java:110)
	at java.lang.Double.parseDouble(Double.java:538)
	at java.text.DigitList.getDouble(DigitList.java:169)
	at java.text.DecimalFormat.parse(DecimalFormat.java:2089)
	at java.text.SimpleDateFormat.subParse(SimpleDateFormat.java:1867)
	at java.text.SimpleDateFormat.parse(SimpleDateFormat.java:1514)
	at java.text.DateFormat.parse(DateFormat.java:364)
	at com.java8.datetime.SimpleDateFormatError.parse(SimpleDateFormatError.java:34)
	at com.java8.datetime.SimpleDateFormatError.lambda$main$0(SimpleDateFormatError.java:18)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)
java.lang.NumberFormatException: multiple points
	at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1890)
	at sun.misc.FloatingDecimal.parseDouble(FloatingDecimal.java:110)
	at java.lang.Double.parseDouble(Double.java:538)
	at java.text.DigitList.getDouble(DigitList.java:169)
	at java.text.DecimalFormat.parse(DecimalFormat.java:2089)
	at java.text.SimpleDateFormat.subParse(SimpleDateFormat.java:1867)
	at java.text.SimpleDateFormat.parse(SimpleDateFormat.java:1514)
	at java.text.DateFormat.parse(DateFormat.java:364)
	at com.java8.datetime.SimpleDateFormatError.parse(SimpleDateFormatError.java:34)
	at com.java8.datetime.SimpleDateFormatError.lambda$main$0(SimpleDateFormatError.java:18)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)
java.lang.NumberFormatException: multiple points
	at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1890)
	at sun.misc.FloatingDecimal.parseDouble(FloatingDecimal.java:110)
	at java.lang.Double.parseDouble(Double.java:538)
	at java.text.DigitList.getDouble(DigitList.java:169)
	at java.text.DecimalFormat.parse(DecimalFormat.java:2089)
	at java.text.SimpleDateFormat.subParse(SimpleDateFormat.java:1867)
	at java.text.SimpleDateFormat.parse(SimpleDateFormat.java:1514)
	at java.text.DateFormat.parse(DateFormat.java:364)
	at com.java8.datetime.SimpleDateFormatError.parse(SimpleDateFormatError.java:34)
	at com.java8.datetime.SimpleDateFormatError.lambda$main$0(SimpleDateFormatError.java:18)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)
java.lang.NumberFormatException: multiple points
	at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1890)
	at sun.misc.FloatingDecimal.parseDouble(FloatingDecimal.java:110)
	at java.lang.Double.parseDouble(Double.java:538)
	at java.text.DigitList.getDouble(DigitList.java:169)
	at java.text.DecimalFormat.parse(DecimalFormat.java:2089)
	at java.text.SimpleDateFormat.subParse(SimpleDateFormat.java:1867)
	at java.text.SimpleDateFormat.parse(SimpleDateFormat.java:1514)
	at java.text.DateFormat.parse(DateFormat.java:364)
	at com.java8.datetime.SimpleDateFormatError.parse(SimpleDateFormatError.java:34)
	at com.java8.datetime.SimpleDateFormatError.lambda$main$0(SimpleDateFormatError.java:18)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)
java.lang.NumberFormatException: multiple points
	at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1890)
	at sun.misc.FloatingDecimal.parseDouble(FloatingDecimal.java:110)
	at java.lang.Double.parseDouble(Double.java:538)
	at java.text.DigitList.getDouble(DigitList.java:169)
	at java.text.DecimalFormat.parse(DecimalFormat.java:2089)
	at java.text.SimpleDateFormat.subParse(SimpleDateFormat.java:1867)
	at java.text.SimpleDateFormat.parse(SimpleDateFormat.java:1514)
	at java.text.DateFormat.parse(DateFormat.java:364)
	at com.java8.datetime.SimpleDateFormatError.parse(SimpleDateFormatError.java:34)
	at com.java8.datetime.SimpleDateFormatError.lambda$main$0(SimpleDateFormatError.java:18)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)
java.lang.NumberFormatException: multiple points
	at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1890)
	at sun.misc.FloatingDecimal.parseDouble(FloatingDecimal.java:110)
	at java.lang.Double.parseDouble(Double.java:538)
	at java.text.DigitList.getDouble(DigitList.java:169)
	at java.text.DecimalFormat.parse(DecimalFormat.java:2089)
	at java.text.SimpleDateFormat.subParse(SimpleDateFormat.java:1867)
	at java.text.SimpleDateFormat.parse(SimpleDateFormat.java:1514)
	at java.text.DateFormat.parse(DateFormat.java:364)
	at com.java8.datetime.SimpleDateFormatError.parse(SimpleDateFormatError.java:34)
	at com.java8.datetime.SimpleDateFormatError.lambda$main$0(SimpleDateFormatError.java:18)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)
java.lang.NumberFormatException: multiple points
	at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1890)
	at sun.misc.FloatingDecimal.parseDouble(FloatingDecimal.java:110)
	at java.lang.Double.parseDouble(Double.java:538)
	at java.text.DigitList.getDouble(DigitList.java:169)
	at java.text.DecimalFormat.parse(DecimalFormat.java:2089)
	at java.text.SimpleDateFormat.subParse(SimpleDateFormat.java:1867)
	at java.text.SimpleDateFormat.parse(SimpleDateFormat.java:1514)
	at java.text.DateFormat.parse(DateFormat.java:364)
	at com.java8.datetime.SimpleDateFormatError.parse(SimpleDateFormatError.java:34)
	at com.java8.datetime.SimpleDateFormatError.lambda$main$0(SimpleDateFormatError.java:18)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)
java.lang.NumberFormatException: multiple points
	at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1890)
	at sun.misc.FloatingDecimal.parseDouble(FloatingDecimal.java:110)
	at java.lang.Double.parseDouble(Double.java:538)
	at java.text.DigitList.getDouble(DigitList.java:169)
	at java.text.DecimalFormat.parse(DecimalFormat.java:2089)
	at java.text.SimpleDateFormat.subParse(SimpleDateFormat.java:1867)
	at java.text.SimpleDateFormat.parse(SimpleDateFormat.java:1514)
	at java.text.DateFormat.parse(DateFormat.java:364)
	at com.java8.datetime.SimpleDateFormatError.parse(SimpleDateFormatError.java:34)
	at com.java8.datetime.SimpleDateFormatError.lambda$main$0(SimpleDateFormatError.java:18)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)
null
null
null
null
null
null
null
null
Thu Oct 05 00:00:00 CST 2023
Thu Oct 05 00:00:00 CST 2023

分析,显然,在多线程环境下,SimpleDateFormat解析字符串到日期对象部分失败;

原因:SimpleDateFormat在解析时,会改变其内部状态以格式化或解析日期。多线程环境下,线程1用的内部状态是线程2修改后的,存在状态不一致的问题;


【2】解决方法

本文给出的解决方法有4种:

  • 方法1:使用 SimpleDateFormat 单例执行解析或格式化操作;
  • 方法2:对调用SimpleDateFormat api的业务方法加锁;如添加 Synchronized关键字,加Lock;
  • 方法3:使用 ThreadLocal<SimpleDateFormat>; 每个线程获取的都是一个SimpleDateFormat单例;
  • 方法4: 使用java8提供的 DateTimeFormatter ;

【2.1】使用 SimpleDateFormat 单例(不推荐)

/**
 * @Description simple data format 解析失败的解决方法1-SimpleDateFormat使用单例(每次调用都新建一个实例)
 * @author xiao tang
 * @version 1.0.0
 * @createTime 2023年10月05日
 */
public class SimpleDateFormatErrorSolutionWithInstance {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        Callable<Date> task = () -> parse("20231005");
        // 线程池
        ExecutorService threadPool = Executors.newFixedThreadPool(10);
        ArrayList<Future<Date>> results = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            results.add(threadPool.submit(task));
        }
        // 获取异步执行结果
        for (Future<Date> result : results) {
            System.out.println(result.get());
        }
        threadPool.shutdown();
    }

    public static Date parse(String dateStr) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd");
        try {
            return simpleDateFormat.parse(dateStr);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null; 
    }
}

结果:

Thu Oct 05 00:00:00 CST 2023
Thu Oct 05 00:00:00 CST 2023
Thu Oct 05 00:00:00 CST 2023
Thu Oct 05 00:00:00 CST 2023
Thu Oct 05 00:00:00 CST 2023
Thu Oct 05 00:00:00 CST 2023
Thu Oct 05 00:00:00 CST 2023
Thu Oct 05 00:00:00 CST 2023
Thu Oct 05 00:00:00 CST 2023
Thu Oct 05 00:00:00 CST 2023

Process finished with exit code 0

【2.2】对业务方法加锁(不推荐)

本文使用了 synchronized,parse方法会同步执行;没有多线程环境;

/**
 * @Description simple data format 解析失败的解决方法2-加锁
 * @author xiao tang
 * @version 1.0.0
 * @createTime 2023年10月05日
 */
public class SimpleDateFormatErrorSolutionWithLock {

    private static final SimpleDateFormat SIMPLE_DATE_FORMAT = new SimpleDateFormat("yyyyMMdd");

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        Callable<Date> task = () -> parse("20231005");
        // 线程池
        ExecutorService threadPool = Executors.newFixedThreadPool(10);
        ArrayList<Future<Date>> results = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            results.add(threadPool.submit(task));
        }
        // 获取异步执行结果
        for (Future<Date> result : results) {
            System.out.println(result.get());
        }
        threadPool.shutdown();
    }

    public synchronized static Date parse(String dateStr) {
        try {
            return SIMPLE_DATE_FORMAT.parse(dateStr);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

【2.3】使用 ThreadLocal<SimpleDateFormat>(特别不推荐,仅了解)

因为ThreadLocal创建的资源属于线程级别,处理不好,容易造成内存泄漏;

/**
 * @Description simple data format 解析失败的解决方法3-使用 ThreadLocal<SimpleDateFormat>
 * @author xiao tang
 * @version 1.0.0
 * @createTime 2023年10月05日
 */
public class SimpleDateFormatErrorSolutionWithThreadLocal {

    private static final ThreadLocal<SimpleDateFormat> THREAD_LOCAL = new ThreadLocal<SimpleDateFormat>() {
        protected SimpleDateFormat initialValue() {
            return new SimpleDateFormat("yyyyMMdd");
        }
    };

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        Callable<Date> task = () -> {
            Date result = parse("20231005");
            // 这里要清除当前线程持有的线程级变量-SimpleDateFormat单例,否则会造成内存泄漏
            THREAD_LOCAL.remove();
            return result; 
        };
        // 线程池
        ExecutorService threadPool = Executors.newFixedThreadPool(10);
        ArrayList<Future<Date>> results = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            results.add(threadPool.submit(task));
        }
        // 获取异步执行结果
        for (Future<Date> result : results) {
            System.out.println(result.get());
        }
        threadPool.shutdown();
    }

    public synchronized static Date parse(String dateStr) {
        try {
            return THREAD_LOCAL.get().parse(dateStr);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

【2.4】使用java8的DateTimeFormatter  (推荐)

/**
 * @Description simple data format 解析失败的解决方法3-使用 java8 DateTimeFormatter
 * @author xiao tang
 * @version 1.0.0
 * @createTime 2023年10月05日
 */
public class SimpleDateFormatErrorSolutionWithJava8DateTimeFormatter {

    private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyyMMdd");

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        Callable<LocalDate> task = () -> parse("20231005");
        // 线程池
        ExecutorService threadPool = Executors.newFixedThreadPool(10);
        ArrayList<Future<LocalDate>> results = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            results.add(threadPool.submit(task));
        }
        // 获取异步执行结果
        for (Future<LocalDate> result : results) {
            System.out.println(result.get());
        }
        threadPool.shutdown();
    }

    public synchronized static LocalDate parse(String dateStr) {
        try {
            return LocalDate.parse(dateStr, DATE_TIME_FORMATTER);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

【3】日期格式化与解析建议

不要使用 SimpleDateFormat;java8提供了更好的和增强的 DateTimeFormatter,且是线程安全的;

也应该避免使用 Date, Calendar 类; 尝试使用 java8 DateTime 类,如 OffsetDateTime, ZoneDateTime, LocalDateTime, LocalDate, LocalTime 等;java8提供的日期时间类比 Date, Calendar 有更好的性能;

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

本地电脑搭建Web服务器并用cpolar发布至公网访问

本地电脑搭建Web服务器并用cpolar发布至公网访问 文章目录 本地电脑搭建Web服务器并用cpolar发布至公网访问前言1. 首先在电脑安装PHPStudy、WordPress、cpolar2. 安装cpolar&#xff0c;进入Web-UI界面3. 安装wordpress4. 进入wordpress网页安装程序5. 利用cpolar建立的内网穿…

回收站里面删除的照片如何恢复?

现在拍照已经成为人们生活中的一种方式&#xff0c;照片为我们保留了许多珍贵而美好的回忆。大家通常会把重要的照片保存在硬盘里&#xff0c;但当不小心把照片移入回收站并彻底删除时&#xff0c;情况就有点糟糕了。那么&#xff0c;回收站里删除的照片还有办法恢复吗&#xf…

leetcode每日一题复盘(10.2~10.8)

leetcode 347 前k个高频元素 关键词:堆排序,优先队列,小根堆 这道题真没想出来怎么做,只能想到哈希统计数目,对优先队列还不是很熟悉,后来看了详解自己重写了一遍 主要思路是用哈希统计每个元素出现次数,再利用优先队列的性质创建小根堆(优先队列默认是从大到小排序,将是一个…

Android 中级控件

目录 一、图形定制1.1 图形Drawable1.2 形状图形1.3 状态列表图形 二、选择按钮2.1 复选框2.2 开关按钮2.3 单选按钮 三、文本输入3.1 编辑框3.2 焦点变更监听器3.3 文本变化监听器 四、对话框4.1 提醒对话框4.2 日期对话框4.3 时间对话框 一、图形定制 1.1 图形Drawable ~~~~…

国庆放假作业5

1、qt实现TCP服务器和客户端 &#xff08;1&#xff09;服务器 头文件 #ifndef MAINWINDOW_H #define MAINWINDOW_H#include <QMainWindow> #include <QTcpServer> #include <QTcpSocket> #include <QList> #include <QMessageBox> #include …

新手学习Python用哪个软件比较好?

对于新手学习Python&#xff0c;有几个常用的集成开发环境&#xff08;IDE&#xff09;可以选择。以下是一些受欢迎的选择&#xff0c;可供题主参考下载使用。 集成开发环境&#xff08;IDE&#xff09; 1. PyCharm&#xff1a; PyCharm 是一款功能强大的 Python IDE&#x…

Vmware 静态网络配置

概述 仅主机模式&#xff08;VMware1&#xff09;&#xff1a;使用host-only的方式是不能和外界通信的&#xff0c;只能够和本机的物理网卡通信 桥接&#xff08;VMnet0&#xff09;&#xff1a;使用桥接的方式使得自己的虚拟机和自己的真实机网卡在同一个网段 NAT&#xff0…

穿越时空的创新:解析云原生与Web3.0的奇妙渊源

文章目录 云原生的崛起云原生的关键特点 Web3.0的崭露头角Web3.0的关键特点 云原生与Web3.0的交汇点1. 去中心化应用程序的部署2. 安全性和可信性3. 去中心化身份管理4. 数据的分布和共享 云原生与Web3.0的未来1. 云原生的区块链支持2. Web3.0的企业应用3. 数据交互的革命4. 新…

FFmpeg:打印音/视频信息(Meta信息)

多媒体文件基本概念 多媒体文件其实是个容器在容器里面有很多流(Stream/Track)每种流是由不同的编码器编码的从流中读出的数据称为包在一个包中包含着一个或多个帧 几个重要的结构体 AVFormatContextAVStreamAVPacket FFmpeg操作流数据的基本步骤 打印音/视频信息(Meta信息…

计算机考研 | 2021年 | 计算机组成原理真题

文章目录 【计算机组成原理2021年真题43题-15分】【第一步&#xff1a;信息提取】【第二步&#xff1a;具体解答】【第三步&#xff1a;总结】 【计算机组成原理2021年真题44题-8分】【第一步&#xff1a;信息提取】【第二步&#xff1a;具体解答】 【计算机组成原理2021年真题…

JavaScript实战游戏逻辑

● 在做猜游戏之前&#xff0c;我们肯定要随机生成一个数字。那就跟之前掷色子的游戏一样 const number Math.trunc(Math.random() * 20) 1; //生成一个1-20的随机数字● 之后&#xff0c;在输入正确的时候我们肯定需要在问号上面显示出来 ● 在测试阶段&#xff0c;我们可…

Java多线程同步锁、Lock锁和等待唤醒机制及代码演示

多线程入门学习路线 线程的生命周期线程的安全问题同步代码块同步方法Lock锁生产者和消费者&#xff08;等待唤醒机制&#xff09; 线程的生命周期 问&#xff1a;sleep方法会让线程睡眠&#xff0c;睡眠时间到了之后&#xff0c;立马就会执行下面的代码吗? 解&#xff1a;sl…

安装使用TinyCore Linux的一些收获

为了学习Linux Shell编程&#xff0c;决定安装一个纯粹的Linux&#xff0c;由于电脑硬件配置较低&#xff0c;选择了最轻量化Llinux操作系统版本TinyCore Linux。 一、TinyCore Linux有三个版本 打开TinyCore Linux的下载页面 http://www.tinycorelinux.net/downloads.html&a…

跨境电商测评内幕及自养号技术教学

现在测评行业的水越来越深了。几年前的测评行业都是邮箱联系老外&#xff0c;大多是一些产品的爱好者&#xff0c;评价也很真实公正。而现在&#xff0c;大量人加入&#xff0c;还有一些中介的参与&#xff0c;及骗子中介、黑心测评买家都纷纷的涌入了市场。 我们公司专业做底…

【计算机网络】高级IO初步理解

文章目录 1. 什么是IO&#xff1f;什么是高效 IO? 2. IO的五种模型五种IO模型的概念理解同步IO与异步IO整体理解 3. 阻塞IO4. 非阻塞IOsetnonblock函数为什么非阻塞IO会读取错误&#xff1f;对错误码的进一步判断检测数据没有就绪时&#xff0c;返回做一些其他事情完整代码myt…

好奇喵 | Tor浏览器——层层剥开洋葱

前言 在之前的博客中&#xff0c;Surface Web —&#xff1e; Deep Web —&#xff1e; Dark Web&#xff0c;我们解释了表层网络、深层网络等的相关概念。 本篇博客介绍Tor浏览器&#xff0c;并且把Tor浏览器的洋葱层层剥开&#xff0c;了解其历史&#xff0c;工作原理&…

c++的发展史以及如何学习

文章目录 1. 什么是C 2. C发展史 3. C的重要性 4. 如何学习C 文章内容 1. 什么是C C语言是结构化和模块化的语言&#xff0c;适合处理较小规模的程序。对于复杂的问题&#xff0c;规模较大的 程序&#xff0c;需要高度的抽象和建模时&#xff0c;C语言则不合适。为了解决软…

【AI视野·今日Robot 机器人论文速览 第四十七期】Wed, 4 Oct 2023

AI视野今日CS.Robotics 机器人学论文速览 Wed, 4 Oct 2023 Totally 40 papers &#x1f449;上期速览✈更多精彩请移步主页 Interesting: &#x1f4da;基于神经网络的多模态触觉感知, classification, position, posture, and force of the grasped object多模态形象的解耦(f…

Pikachu靶场——远程命令执行漏洞(RCE)

文章目录 1. RCE1.1 exec "ping"1.1.1 源代码分析1.1.2 漏洞防御 1.2 exec "eval"1.2.1 源代码分析1.2.2 漏洞防御 1.3 RCE 漏洞防御 1. RCE RCE(remote command/code execute)概述&#xff1a; RCE漏洞&#xff0c;可以让攻击者直接向后台服务器远程注入…

二叉树经典例题

前言&#xff1a; 本文主要讲解了关于二叉树的简单经典的例题。 因为二叉树的特性&#xff0c;所以关于二叉树的大部分题目&#xff0c;需要利用分治的思想去递归解决问题。 分治思想&#xff1a; 把大问题化简成小问题&#xff08;根节点、左子树、右子树&#xff09;&…