java线程实现及线程池的使用

Java线程实现

线程把处理器的调度和资源分配分开,是cpu的最小调度单位。多个线程可以共享进程的内存资源,又可以独立调度。java线程关键方法都是通过高效的本地方法实现的。Java线程的主要实现方式有三种:内核实现、用户实现、内核用户混合实现。

1.内核实现

内核线程就是由内核调度、映射的线程。支持多线程的内核称为多线程内核。这种线程,所有操作都需要系统调度,需要在内核态和用户态切换,系统调用代价比较高。

2.用户实现

这种线程建立在用户空间,在用户态中建立、同步、销毁,不需要内核操作。这种操作非常快速且消耗低,可以支持更多的线程。但是线程阻塞和处理器的分配等功能在不借助内核态的情况下实现起来非常难,所以很少单独使用。

3.内核用户混合实现

最后是上面两种方式的结合,通过用户线程实现线程的创建、切换、析构等,而通过内核提供的轻量级进程实现线程的调度及处理器的映射。

JDK采用的是第二种方式即内核实现,每一个java线程都会对应内核提供的一条轻量级进程。

Java线程调度

线程调度就是分配处理器使用权的过程,主流的调度方式有两种:协同式线程调度和抢占式线程调度。
协同式线程调度中线程的执行时间由线程自身控制,线程执行完后,要主动通知系统切换线程。这种方式实现起来比较简单,且不存在线程同步问题。但是由于线程自身控制切换操作,若某个线程出现问题,可能会导致系统的崩溃。
抢占式线程调度中线程的调度由系统控制,这样就可以避免某个线程挂掉而导致整个系统崩溃。我们的jdk线程就是采用的这种调度方式,系统运行起来会更加的稳定。
当然我们可以通过设置线程的优先级来提高某些线程的执行几率,但是这种方式存在很大的不确定性。因为线程优先级的实现依赖于具体的操作系统平台,不同的平台优先级实现不同,可能会导致java中不同线程优先级在一些平台上却是按相同优先级进行调度的,另外操作系统还可能根据某些策略来忽略线程优先级,所以线程在cpu中的具体调度策略和执行顺序是不可知的,我们不能想当然的臆测线程的执行逻辑。

java线程生命周期

Java线程主要存在5中状态:新建(new)、运行(runnable)、无限期等待(waitting)、有限期等待(timed waiting)、阻塞(blocked)、结束(terminated)。
1.新建:创建后尚未启动的线程。
2.运行:正在执行及等待cpu时间片的线程。
3.无限期等待:不会被分配时间片,等待唤醒的线程。主要包括:使用了Object.wait()、Thread.join()、LockSupport.park()等无timeout参数方法的线程。
4.有期限等待:这种状态的线程也不会被分配时间片,但是在一定时间后系统会自动唤醒它们。主要包括:使用了Thread.sleep()及上面3中几个带timeout参数方法的线程。
5.结束:已经终止的线程。

线程池的优点

由于java线程是通过内核中的轻量级进程实现的,线程创建和销毁都需要切换到内核态,线程生命周期开销非常高。同时新建线程也会导致请求延迟一会才能被处理。另外由于每个线程都会分配一些独立的内存空间,若创建过多的线程会增加内存的占用,同时大量空闲的线程持有对象强引用,会给垃圾回收带来很大的压力,大量的线程竞争cpu资源也会产生很大的性能开销,降低程序的执行速度。在后端服务中经常会出现某些rpc接口的延迟抖动会导致整个服务所有接口性能下降,主要就是因为:依赖的外部接口抖动延迟响应时间变长,请求接口的线程阻塞同时大量请求重试,这时大量新线程被创建,cpu频繁进行用户态内核切换及大量线程争用cpu,导致服务性能逐步下降。线程池的出现非常好的解决了上面的问题,现在代码中已经很少能见到直接new Thread的操作了,有这种操作的程序猿要么是扫地圣僧,要么就是删库跑路的狠人了,哈哈哈哈。

线程及线程池使用注意点

1.尽量避免使用守护线程

Jvm在正常关闭时,会先并行执行关闭钩子及所有已提交和执行中的普通线程,然后去处理定义了finalize方法的对象,做好这些后就会直接结束运行,不会管是否有是正在执行的守护线程,若我们在自定义的守护线程中进行了业务操作或IO操作之类的,就可能造成意外的业务错误。

2.避免改变线程优先级

jvm中的线程优先级只能作为线程调度的参考,线程并不一定按优先级高低顺序执行,这是因为jvm中线程优先级是通过映射系统调度优先级实现的,依赖于特定的平台,而不同平台实现的调度优先级不同,因此两个不同优先级的线程可能被映射成相同的调度优先级。除此之外使用优先级还可能会导致某些线程一直无法获取cpu的调度,进而导致线程的饥饿问题。

3.依赖性任务可能导致线程的饥饿死锁

在线程池中,如果任务依赖于其他任务,并且依赖的任务也在同一线程池中执行,那么便可能产生死锁。当依赖的任务被拒绝或者一直停留在工作队列中,那么任务就会一直阻塞并一直占用线程,队列中任务也获取不到这个线程,就会产生死锁,这种死锁被称为线程饥饿死锁。

4.线程池中的任务应该是同类型的独立任务

计算密集型任务一定不能和IO密集型共用同一个线程池。道理其实很简单,我们举个例子:我们有两个线程并行执行,其中一个需要9毫秒,而另一个需要1毫秒,当我们采用串行执行时任务执行所需时间为10毫秒,而当我并行执行时任务执行所需时间为9毫秒,线程的切换可能还需要一些时间(假设2毫秒),这样算下来抛除线程切换造成的cpu资源浪费,结果并行时间反而还没有串行快,吃力不讨好啊。实际上计算密集型和IO密集型任务不但应该使用不同的线程池,连线程池大小的配置策略也是大不相同,小伙伴们要注意下。由此我们可以进一步推出:执行时间较长的任务不能和执行时较短的任务共用一个线程池,执行时间较长的任务不仅可能造成线程阻塞,也会增加执行时间较短任务的响应时间,甚至当长时间任务的qps大于线程池中的线程数量时,可能会出现所有线程都在执行长时间任务的现象,严重影响服务的性能。总而言之,线程池中的任务应该是同类型的独立任务,并且我们需要根据任务类型去合理配置线程池的线程数量。

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

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

相关文章

SOAP:简单对象访问协议

见:https://baike.baidu.com/item/%E7%AE%80%E5%8D%95%E5%AF%B9%E8%B1%A1%E8%AE%BF%E9%97%AE%E5%8D%8F%E8%AE%AE/3841505?fraladdin&fromid4684413&fromtitleSOAP 简单对象访问协议 SOAP(简单对象访问协议)一般指简单对象访问协议 …

程序调试

对拍 $ Windows $ 下的对拍程序 借助 \(Windows\) 脚本echo off :loop r.exe > input.in coronas.exe <input.in > output.a std.exe <input.in > output.b fc output.a output.b if not errorlevel 1 goto loop 一直没有找到怎样能控制对拍次数,今天终于醒悟,可…

不怕烧钱怕翻车:雷军与马化腾现场“过招”

说起微信&#xff0c;很多时尚潮人都很熟悉。这款软件可以发送语音信息、可以在有无线网络的地方免费发送、甚至只需摇一摇就能找到在你附近的用户&#xff0c;这些方便、时尚、新颖的元素使微信受到了很多用户的喜爱&#xff0c;也夺得了大量的市场。其实&#xff0c;在微信发…

php基础(一)

1、header(contentType:text/html,charset:utf-8)设置编码 2、查找字符串最后一次出现的 strrpos() 查找字符第一次出现的 strpos 3、array_sum() 返回数组值得和 4、func_num_args() 求函数参数的个数 5、func_get_args() 获取函数的所有参数 6、匿名函数 例子 $anonymityfun…

Thread.yield()和Thread.sleep(0)

关于Thread.yield()和Thread.sleep(0)的语义问题真是一个让人挠头的问题&#xff0c;翻了好多资料&#xff0c;在java6语言规范中看到了一段这样的描述&#xff1a; 重点在红框中&#xff0c;简而言之就是&#xff1a;sleep(0)和yield()的实现不需要任何可见的效果。那么在实现…

OOA:面向对象

见&#xff1a;https://baike.baidu.com/item/OOA/3659916?fraladdin OOA:面向对象&#xff1a; Object-Oriented Analysis&#xff08;面向对象分析方法&#xff09;是确定需求或者业务的角度&#xff0c;按照面向对象的思想来分析业务。例如&#xff1a;OOA只是对需求中描述…

DCT原型 ——傅里叶级数

傅里叶级数 法国数学家傅里叶发现&#xff0c;任何周期函数都可以用正弦函数和余弦函数构成的无穷级数来表示&#xff08;选择正弦函数与余弦函数作为基函数是因为它们是正交的&#xff09;&#xff0c;后世称为傅里叶级数&#xff08;法语&#xff1a;srie de Fourier&#xf…

c 递归算法

#include <stdio.h>double factorial(unsigned int i) {if(i < 1){return 1;}return i * factorial(i - 1); } int main() {int i 15;printf("%d 的阶乘为 %f\n", i, factorial(i));return 0; } 转载于:https://www.cnblogs.com/sea-stream/p/9822437.htm…

红黑树和B+树

&#xff08;一&#xff09;红黑树 红黑树是一种自平衡二叉查找树&#xff0c;也被称为"对称二叉B树"&#xff0c;它可以在O(logn)时间内利用 O(logn)的空间来完成查找、插入、删除操作。红黑树的读操作与普通二叉查找树相同&#xff0c;而插入和删除操作可能会破坏…

策略模式、观察者模式、代理模式、装饰模式 应用场景和实现

有个大神写的很好&#xff1a; 参考&#xff1a;设计模式学习笔记&#xff08;四&#xff1a;策略模式&#xff09; 参考&#xff1a;设计模式学习笔记&#xff08;二&#xff1a;观察者模式&#xff09; 参考&#xff1a;设计模式学习笔记-代理模式 参考&#xff1a;设计模式-…

DQL、DML、DDL、DCL的概念与区别

http://blog.csdn.net/tomatofly/article/details/5949070 SQL语言的分类 SQL语言共分为四大类&#xff1a;数据查询语言DQL&#xff08;Data Query Language&#xff09;&#xff0c;数据操纵语言DML&#xff0c;数据定义语言DDL(Data Definition Language)&#xff0c;数据…

python学习总结

1.python环境搭建方便&#xff0c;只需要安装python解释器 2.python把任意数据类型赋值给变量&#xff0c;不用定义类型 3.Python的整数浮点数没有大小限制&#xff0c;不用担心超过数值范围。比如java的 int&#xff0c;long 4.python自带最常用的list列表和dicitonary字典&am…

李国杰院士:国内开源社区的崛起需要一个过程

[CSDN.NET 付江/文]日前&#xff0c;在第二届“龙芯杯”中国开源软件设计大赛启动仪式上&#xff0c;CSDN记者专访了中国工程院院士、第三世界科学院院士李国杰。李国杰院士就国产基础软件现状、面临的机遇和挑战、开源环境以及生态系统建设等话题分享了自己的看法。 打造自主…

SuperMap iObject入门开发系列之五管线属性查询

本文是一位好友“托马斯”授权给我来发表的&#xff0c;介绍都是他的研究成果&#xff0c;在此&#xff0c;非常感谢。 管线属性查询功能针对单一管线图层进行特定的条件查询&#xff0c;然后将查询结果输出为列表&#xff0c;并添加点位闪烁功能&#xff0c;例如查询污水管线中…

三类基于贪心思想的区间覆盖问题

一、区间完全覆盖问题 问题描述&#xff1a;给定一个长度为m的区间&#xff0c;再给出n条线段的起点和终点&#xff08;注意这里是闭区间&#xff09;&#xff0c;求最少使用多少条线段可以将整个区间完全覆盖。 样例&#xff1a;一个长度为8的区间&#xff0c;可选的线段有[2,…

ubuntu 常用软件和命令

永久修改屏幕的分辨率   sudo gedit .profile 将下面的四句话加入。.profile文件的最后   cvt 1280 768   xrandr --newmode "1280x768_60.00" 79.50 1280 1344 1472 1664 768 771 781 798 -hsync vsync   xrandr --addmode Virtual1 "1280x768_60.00&q…

Eclipse搭建Android开发环境(安装ADT,Android4.4.2)

见&#xff1a;http://blog.csdn.net/zht666/article/details/29837777 使用Eclipse做Android开发&#xff0c;需要先在Eclipse上安装ADT&#xff08;Android Development Tools&#xff09;插件。 1.安装JDK 1.7 JDK官网http://www.oracle.com/technetwork/java/javase/downlo…

C语言 位操作简析

位运算 前面介绍的各种运算都是以字节作为最基本位进行的。 但在很多系统程序中常要求在位(bit)一级进行运算或处理。&#xff23;语言提供了位运算的功能&#xff0c; 这使得&#xff23;语言也能像汇编语言一样用来编写系统程序。 一、位运算符&#xff23;语言提供了六种位运…

算法:输入一个链表,输出该链表中倒数第k个结点。

算法&#xff1a;输入一个链表&#xff0c;输出该链表中倒数第k个结点。《剑指offer》 思路加到注释里面了&#xff1b; 1&#xff1a;两个if判断是否返回值为空&#xff0c;首个为空&#xff0c;没有第k个值&#xff1b; 2&#xff1a;for循环找到倒数第k个值&#xff0c;返回…

Spring事务那些事儿

&#xff08;一&#xff09;事务的隔离级别 大家都知道事务有四个属性&#xff0c;即ACID&#xff08;原子性、一致性、隔离性、持久性&#xff09;。这四个里面稍微难理解点的是一致性和持久性。所谓的一致性是指&#xff1a;事务执行前后数据的一致性状态&#xff0c;例如事…