在线客服
扫描二维码
下载博学谷APP
扫描二维码
关注博学谷微信公众号
Java开发线程特点基础知识分享,线程提供的一些不太常用的方法及技术不管是初学者还是高级用户或者是Java专家都需要了解。掌握线程、进程、多线程、并发、并行、同步、异步、线程类常见方法、线程生命周期、线程安全问题、死锁、生产者和消费者等多线程核心知识点。

初学者阶段:
1、线程名
程序中的每个线程都有一个名字,创建线程的时候会给它分配一个简单的Java字符串来作为线程名。默认的名字是”Thread-0″, “Thread-1″, “Thread-2″等。
线程名可变,可在运行时修改它的名字,而不用在初始化的时候就指定好。name字段其实是一个简单的字符串对象,它能达到2³¹-1个字符那么长足够用了。这个名字并不是一个唯一性的标识,因此不同的线程也可以拥有同样的线程名。还有一点不要把null用作线程名否则会抛出异常。
使用线程名来调试问题
既然可以设置线程名,如果遵循一定的命名规则出问题的时候排查起来就能更容易。在处理用户请求的时候可以将事务ID追加到线程名后面,能减少排查问题的时间。
2. 线程优先级
线程还有一个有意思的属性优先级。线程的优先级介于1 (MINPRIORITY)到10 (MAXPRIORITY)之间,主线程默认是5(NORM_PRIORITY)。每个新线程都默认继承父线程的优先级,如果没设置过,所有线程的优先级都是5。这个是通常被忽视的属性,可以通过getPriority()与setPriority()方法来获取及修改它的值。线程的构造函数里是没有这个功能。
什么地方会用到优先级?
不是所有的线程都是平等的,有的线程需要立即引起CPU重视,而有些线程则只是后台任务。优先级就是用来把这些告诉给操作系统的线程调度器。在Takipi中开发的一错误跟踪及排查的工具,负责处理用户异常的线程的优先级是MAX_PRIORITY,而那些只是在上报新的部署情况的线程,优先级就要低一些。优先级高的线程从JVM的线程调度器那得到的时间会多一些,但其实并非是这样的。
在操作系统层面每一个新线程都会对应一个本地线程,所设置的Java线程的优先级会被转化成本地线程的优先级,这个在各个平台上不一样。在Linux上可以打开“-XX:+UseThreadPriorities”选项来启用这项功能。线程优先级只是所提供的一个建议,和Linux本地的优先级相比Java线程的优先级并不能覆盖全所有的级别(Linux共有1到99个优先级,线程的优先级在是-20到20之间)。最大的好处所设定的优先级能在每个线程获得的CPU时间上有所体现,不过完全依赖于线程优先级的做法不推荐。
进阶阶段:
3、线程本地存储
ThreadLocal是在Thread类之外实现的一个功能(java.lang.ThreadLocal),但它会为每个线程分别存储一份唯一的数据。正如它的名字所说的,它为线程提供了本地存储,也就是说所创建出来变量对每个线程实例来说都是唯一的。和线程名,线程优先级类似可以自定义出一些属性,像存储在Thread线程内部一样。
全局变量不是什么好事
ThreadLocal可以用来存储事务ID。如果代码中出现未捕获异常的时候它就相当有用了,最佳实践是设置一个UncaughtExceptionHandler,这个是Thread类本身就支持的,但是得自己去实现一下这个接口。一旦执行到了UncaughtExceptionHandler里,几乎没有任何线索能够知道到底发生了什么事情了。这会儿能获取到的就只有Thread对象,之前导致异常发生的所有变量都无法再访问了,因为那些栈帧都已经被弹出了。一旦到了UncaughtExceptionHandler里,这个线程就只剩下最后一口气了,唯一能抓住的最后一根稻草就是ThreadLocal。
4、用户线程及守护线程
Thread类。程序中的每个线程都会有一个状态,是用户状态或是守护状态。换句话说,前台线程或是后台线程,主线程默认是用户线程,每个新线程都会从创建它的线程中继承线程状态。如果把一个线程设置成守护线程,那么它所创建的所有线程都会被标记成守护线程。如果程序中的所有线程都是守护线程的话,那么这个进程便会终止。可以通过Boolean .setDaemon(true)和.isDaemon()方法来查看及设置线程状态。
什么时候会用到守护线程?
如果进程不必等到某个线程结束才能终止,那么这个线程就可以设置成守护线程。这省掉了正常关闭线程的那些麻烦事,可以立即将线程结束掉。换个角度来说,如果一个正在执行某个操作的线程必须要正确地关闭掉否则就会出现不好的后果的话,那么这个线程就应该是用户线程。通常都是些关键的事务,比方说,数据库录入或者更新这些操作不能中断。
高级阶段:
5、处理器亲和性
这里要讲的会更靠近硬件,当软件遇上了硬件。处理器亲和性使得能够将线程或者进程绑定到特定的CPU核上。这意味着只要是某个特定的线程,肯定只会在某个特定的CPU核上执行。通常来讲如何绑定是由操作系统的线程调度器根据它自己的逻辑来决定的,它很可能会将前面提到的线程优先级也一并考虑进来。
这么做的好处在于CPU缓存。如果某个线程只会在某个核上运行,那么它的数据恰好在缓存里的概率就大大提高了。如果数据正好就在CPU缓存里,那么就没有必要重新再从内存里加载了。所节省的这几毫秒时间就能用在刀刃上,在这段时间里代码可以马上开始执行,也就能更好地利用所分配给它的CPU时间。当然了,操作系统层面可能会存在某种优化,硬件架构当然也是个很重要的因素,但利用了处理器的亲和性至少能够减小线程切换CPU的机率。
由于掺杂着多种因素处理器亲和性到底对吞吐量有多大的影响,最好还是通过测试的方式来进行证明。也许这个方法并不是总能显著地提升性能,但至少有一个好处就是吞吐量会相对稳定。亲和策略可以细化到非常细的粒度上取决于具体想要什么,高频交易行业便是这一策略最能大显身手的场景之一。
— 申请免费试学名额 —
在职想转行提升,担心学不会?根据个人情况规划学习路线,闯关式自适应学习模式保证学习效果
讲师一对一辅导,在线答疑解惑,指导就业!
相关推荐 更多
Java基础 Jvm如何加载类?如何分配空间?
Java基础 Jvm如何加载类?如何分配空间?指的是将 class 文件的二进制数据读入到运行时数据区(JVM在内存中划分的)中,并在方法区内创建一个 class 对象JVM 运行起来时就给内存划分空间,这块空间就称为运行时数据区。
9752
2019-06-03 15:41:22
Java基础语法之Switch语句讲解和练习
在Java中Switch语句是比较常用的语句,Switch语句一般用于一个表达式和多个值进行比较。因此,对于刚开始入门学习Java基础语法的朋友来讲,Switch语句是必须掌握的一个基础知识点。本文将讲解Switch语句的定义、格式和执行流程,为了进一步巩固大家对知识点的掌握,本文还为大家准备Switch语句的练习,下面一起来看看吧!
7371
2019-12-25 11:16:29
如何用Java查询个人信息?代码怎么写?
如何用Java查询个人信息?编程写好相应的规则,按照规则执行,在一定程度上大大提高了工作效率,在我们生活中的应用无处不在,当你面临公司大量的人员数据如何准确查询处理你想要的数据呢?
8959
2020-02-11 17:13:36
Redis基础课程学什么?
缓存是目前企业级应用中的核心组成部分,当今主流的电商、生活服务、直播等领域都离不开缓存的使用。Redis作为当下主流的缓存技术,已成为互联网企业的不二首选,基于Redis集群的缓存结构设计已在同领域内占据半壁江山。本文主要为大家介绍Redis的基础课程,让大家清楚地了解Redis基础课程学什么,有学习需要的朋友不妨来了解一下。
5913
2020-04-24 16:22:40
成为Java架构师需要具备的基础知识有哪些?
行业中对于Java架构师的要求较高,需要掌握秒杀技术架构百万并发代理设计、动静分离架构思想、熔断限流实战、异步消息通信设计、垂直日志收集设计、秒杀冷热商品抢单实战、LVS+Nginx集群抢单百万并发实战等技术,入门学习了解可以先学习一下基础的部门。
5404
2020-11-20 14:46:09
