在线客服
扫描二维码
下载博学谷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,大家都知道它是一门典型的面向对象的编程语言。但是对于面向对象,可能还有许多人并不清楚。那么面向对象是什么?有哪些特征呢?本文就来带大家好好认识一下面向对象。面向对象是一种软件的开发方法,它的特征归纳起来就是三点,即封装、继承和多态。下面是关于面向对象的深入介绍:
4841
2019-10-31 10:10:10
优秀的Spring Cloud开源项目整理推荐
无论是对于初学者,还是有一定工作经验的程序员来讲,Spring Cloud开源项目都是一笔宝贵的财富。本文整理了十个优秀的开源项目,分别是spring-cloud-examples、spaascloud-master、spring-cloud-rest-tcc、awesome-spring-cloud、xxpay-master等等,感兴趣的朋友赶紧看下去吧!
5908
2019-12-25 14:35:27
Java 基础语法之数据类型学习笔记
众所周知,Java 是一个强类型语言,Java 中的数据必须明确数据类型。本文将和大家一起来梳理一下数据类型的相关学习笔记,主要有两种数据类型,即基本数据类型和引用数据类型。还包括了类型转化的相关知识点,有学习需要的小伙伴一起来看看吧!
4549
2020-05-15 11:00:47
Java基础之for循环使用练习
Java语言与现实生活是紧密联系的,因此在Java语言中也有让代码重复执行的循环结构。其中Java开发中使用最多的是 for 循环,并非它有多特殊,知识习惯而已。比如有一个需求:把“爱的魔力转圈圈”输出5遍。你当然可以写5次输出语句,但是太low,也过于冗杂。下面我们来讲讲for循环,然后再做一做相关的使用练习。
3780
2020-08-18 12:24:49
使用Spring框架的优点有哪些?
Spring是java企业级应用的开源开发框架,主要用来开发Java应用,但有些扩展是针对构建J2EE平台的web应用。Spring框架目标是简化Java企业级应用开发,并通过POJO为基础的编程模型促进良好的编程习惯。Spring最核心的两个点就是IOC和AOP。
3560
2021-02-03 14:27:19