从Linux的errno到Java的ThreadLocal

简介:

Linux里的errno


在Linux下执行系统调用时,一般会有一个返回值表示成功或失败,但是这个值只说明了成功或失败,却没有说明是如何成功或失败的。

errno就是为了解决这个问题的,系统调用会把错误号设置为errno,我们通过错误号就能知道失败的原因。还可以使用strerror打印出这个错误号对应的字符串说明。老版本的Linux需要加上extern int errno,现在直接引入<errno.h>就行了.

errno示例:

wKioL1WbuPjQ9_gzAAHrJFspGzI545.jpg

现在的问题来了。假如我有两个线程,代码如下:

wKiom1Wbt2CSHc8DAAC4FjSCW0c854.jpg

errno是一个全局变量,那么假如执行顺序为 1-1,2-1,1-2,2-2,线程1打印出的errno就是线程2的,这就是errno的问题,线程不安全。

但是测试很多次,结果都是正确的。虽然你用这个errno是当作一个全局变量的,但是实际上是个宏。用gcc -E将源代码的宏展开,可以看到,errno被替换成了一个函数。

wKioL1WbuZuyhJVTAAJJJiKqJHo234.jpg

使用man errno查看对errno的解释,可以看到下面一句话:

       errno  is  defined  by  the ISO C standard to be a modifiable lvalue of
       type int, and must not be explicitly declared; errno may  be  a  macro.
       errno  is  thread-local;  setting  it in one thread does not affect its
       value in any other thread.


所以errno并不是一个全局变量,而是一个thread-local,每个线程都有一个。我们可以自己实现一个errno。


自己写一个errno


仅仅演示一下errno的基本原理,使用一个map存放各个线程的errno,而这个map的key就是threadId。系统调用执行完毕后,会将错误码写入此线程对应的errno中。代码中的系统调用是一个假系统调用,some_system_call()。

实际开发中,对于开发者,他实际上是看不到set_errno(),get_errno()这些函数的,他只需要取errno就行了。

wKiom1Wbudzhz-3IAAUruAEgEOY812.jpg


Java的ThreadLocal


Java的ThreadLocal和Linux的errno是一样的,只不过errno对开发者来说更简单一点,而且只能取,当作一个变量就行了。

wKioL1WbvwTCsMG7AAI8sT9dyJo690.jpg

只定义了一个ThreadLocal,但是各个线程里的都不一样。

自己实现一个ThreadLocal


其实ThreadLocal也和上面我自己实现的errno类似,用了一个Map,感兴趣的可以去看一下jdk源码,我写了一个很简陋的MyThreadLocal,Java的ThreadLocal的原理大致就是这样的。直接将上面的代码的ThreadLocal替换成MyThreadLocal就可以运行,当然这个MyThreadLocal太简单,仅仅为了介绍原理。

wKioL1WbwHKxdsl-AAJ3jZYOBEA724.jpg


本文转自nxlhero 51CTO博客,原文链接:http://blog.51cto.com/nxlhero/1671798,如需转载请自行联系原作者

相关文章
|
5月前
|
Java Linux Apache
Apache NetBeans 27 (macOS, Linux, Windows) - Java 等多语言开源跨平台 IDE
Apache NetBeans 27 (macOS, Linux, Windows) - Java 等多语言开源跨平台 IDE
360 5
Apache NetBeans 27 (macOS, Linux, Windows) - Java 等多语言开源跨平台 IDE
|
9月前
|
存储 Java
【源码】【Java并发】【ThreadLocal】适合中学者体质的ThreadLocal源码阅读
前言 下面,跟上主播的节奏,马上开始ThreadLocal源码的阅读( ̄▽ ̄)" 内部结构 如下图所示,我们可以知道,每个线程,都有自己的threadLocals字段,指向ThreadLocalMap
567 81
【源码】【Java并发】【ThreadLocal】适合中学者体质的ThreadLocal源码阅读
|
9月前
|
存储 缓存 安全
【Java并发】【ThreadLocal】适合初学体质的ThreadLocal
ThreadLocal 是 Java 中用于实现线程本地存储(Thread-Local Storage)的核心类,它允许每个线程拥有自己独立的变量副本,从而在多线程环境中实现线程隔离,避免共享变量带来的线程安全问题。
254 9
【Java并发】【ThreadLocal】适合初学体质的ThreadLocal
|
8月前
|
存储 安全 Java
深入探究Java中ThreadLocal的工作原理和用途
总结起来,ThreadLocal是Java多线程编程中一个非常有用的工具,通过为每个线程分配独立的变量副本,实现线程隔离,避免资
182 9
|
7月前
|
Java Linux 开发者
linux 查看java的安装路径
本指南详细介绍Java环境的安装验证与配置方法,包括检查Java版本、确认环境变量JAVA_HOME是否正确配置,以及通过which和readlink命令手动定位Java安装路径。同时提供系统级环境变量配置步骤,并给出多版本管理建议。适用于Linux系统用户,特别是需要在服务器或Docker容器中部署Java环境的开发者。注意操作时需具备相应权限,确保路径设置准确无误。
|
9月前
|
监控 数据可视化 Java
调试技巧 - 用Linux命令排查Java问题
总的来说,使用Linux命令来排查Java问题,需要一定的实践经验和理论知识。然而,只要我们愿意花时间深入了解这些工具,我们就能够熟练地使用它们来分析和解决问题。此外,这些工具只是帮助我们定位问题,真正解决问题需要我们对Java和JVM有深入的理解,并能够读懂和分析代码。
529 13
|
10月前
|
存储 设计模式 Java
重学Java基础篇—ThreadLocal深度解析与最佳实践
ThreadLocal 是一种实现线程隔离的机制,为每个线程创建独立变量副本,适用于数据库连接管理、用户会话信息存储等场景。
375 5
|
算法 Java Linux
java制作海报七:java Graphics2D 合成图片 在 linux下中文不显示,echarts图上的中文也不显示问题
这篇文章讨论了在Linux环境下使用Java Graphics2D合成图片时遇到的中文显示问题,并提供了解决方案,包括如何在Linux系统中添加中文字体库。
251 1
java制作海报七:java Graphics2D 合成图片 在 linux下中文不显示,echarts图上的中文也不显示问题
|
Java Linux
java读取linux服务器下某文档的内容
java读取linux服务器下某文档的内容
141 3
java读取linux服务器下某文档的内容