Java并发编程解惑

提示:
1、浏览此博文之前 建议先学习一下Java 8的新特性;
2、有一些项目开发经验,才能更好地理解并发编程;

学习路线

  • Java并发编程解惑
  • 1.1走进并发编程
    • 1.1.2认识一下CPU
    • 1.1.3CPU品牌
    • 1.1.4摩尔定律
    • 1.1.5Amdahl定律
  • 1.2什么是并行与并发
  • 1.3进程与线程
  • 1.4如何查看进程下的线程及CPU占用率
    • 1.4.1Window环境
    • 1.4.2Linux环境
  • 1.5下载JDK源码
  • 1.6Java底层如何创建一个线程
  • 1.7线程有哪些实现方式?
      • 1、使用内核线程实现;
      • 2、使用用户线程实现;
      • 3、使用用户线程 + 内核线程混合实现;
    • 1.7.1内核线程
    • 1.7.2Linux系统能创建多少个Java线程?
    • 1.7.3用户线程
    • 1.7.4用户线程 + 内核线程混合实现
  • 1.8再认识一下Java中的线程
  • 1.9在Java中创建线程的几种方式

1.1走进并发编程

  • 为什么要使用并发编程?
  • 1、为了获得更好的性能;
    2、业务上的需要,确实需要使用并行处理,比如服务器端编程、图像处理;
    1.1.1计算机的基本组成

1.1.2认识一下CPU

  • CPU = 控制器 + 运算器
  • 计算机的运算和控制核心称为处理器(Processor),即中央处理单元(Central Processing Unit,CPU),微型机中的处理器通常采用的是一块大规模集成的电路芯片,所以也被称为微处理器(Microprocessor),它代表着整个微型机系统的性能,因此通常将以微处理器为核心构造的计算机称为微型计算机;

1.1.3CPU品牌

国产:龙芯中科技术股份有限公司 龙芯CPU

1.1.4摩尔定律

  • 1965年,英特尔联合创始人戈登·摩尔提出以自己名字命名的「摩尔定律」,指的就是集成电路上可容纳的元器件(晶体管)的数量每隔18至24个月就会增加一倍,性能也将提升一倍;
    然而这一定律在经历半个世纪之后受到了挑战,我们无法无限制地增加晶体管的数量,摩尔定律要失效了?
  • 面对这种情况,科学家和工程师们想出了另外一个办法,那就是把独立的计算单元核心整合到一个CPU中,于是就出现了多核CPU,以增加核心数的方式提升CPU的整体性能;
  • 我们一般的个人电脑有一颗cpu,里面是多个核心,比如2核、4核,6核、8核等,而专业的服务器则有多颗cpu,每颗cpu里面有8核或更多的内核,最终内核总数可能达到上百个内核;
  • 一般情况下,cpu核心数 和 线程数 是1:1的关系,但是Intel引入了超线程技术,使得cpu核心数 和 线程数 形成1:2的关系,即每个核心有2个线程,比如4核8线程,8核16线程;
  • 多核CPU是硬件发展出现瓶颈后的解决方案,他们不负责任地把多个内核塞进同一个CPU中,然而这一方案却苦了软件开发人员,软件开发人员不得不面对头疼的并发编程问题;
  • 如何让多核CPU正确地工作,比如多线程之间如何保证线程安全,保证运算结果不出现错误等,这些问题都需要软件开发者来进行考虑,那么现在已然是多核cpu的时代,已不能期望回到单核时代,我们就不得不研究并发编程;

1.1.5Amdahl定律

  • 多核CPU的出现,让我们需要采用并行处理程序,采用并行处理程序能提升多少性能?有著名的阿姆达尔定律,它是一个计算机科学界的经验法则,因吉恩·阿姆达尔而得名,它代表了处理器并行运算之后效率提升的能力;
  • 计算公式:S=1/(a+(1-a)/n)
  • 其中,a为串行计算部分所占比例,n为并行处理结点个数。这样,当a=0时,最大加速比s=n;当a=1时,最小加速比s=1;当n→∞时,极限加速比s→ 1/a,这也就是加速比的上限,例如,若串行代码占整个代码的25%,则并行处理的总体性能不可能超过4,这一公式已被学术界所接受,并被称做“阿姆达尔定律”(Amdahl law);
  • Amdahl定律通过系统中并行化与串行化的比重来描述多处理器系统能获得的运算加速能力,摩尔定律则用于描述处理器晶体管数量与运行效率之间的发展关系,这两个定律的更替代表了近年来硬件发展从追求处理器频率到追求多核心并行处理的发展过程;

1.2什么是并行与并发

  • 并发(Concurrent):是指在单核CPU上同时运行多个程序,并发不是真正意义上的“同时进行”,而是通过抢占CPU时间片去执行;
    单核cpu下,线程实际是串行执行的。只是由于 cpu 在线程间(时间片很短)的切换非常快,让人感觉像是同时运行的;
    所以这种线程轮流使用 CPU 的做法称为并发:Concurrent;

  • 并行(Parallel):是指在多个CPU或者一个多核CPU上同时运行多个程序,每个CPU或者多核CPU可以分别运行程序,两个程序互不抢占CPU资源,可以真正做到同时进行,这种方式我们称之为并行:Parallel;

以上的讨论其实与语言无关,不管是C、Java都是如此,都可以使用并发编程;

1.3进程与线程

操作系统课程对进程的定义:
进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。在早期面向进程设计的计算机结构中,进程是程序的基本执行实体,在当代面向线程设计的计算机结构中,进程是线程的容器;

比如通过windows资源管理器看到的都是进程,进程是操作系统管理的基本单元;
**线程是进程中独立运行的子任务,**比如DingTalk是一个进程,里面运行了很多子任务,像聊天信息发送线程、远程视频或语音会议线程、文件上传下载线程等等,这些子任务我们就理解为线程,这些线程可以同时运行,这些子任务同时运行带来的好处就是在同一时间内可以运行多种不同类型的任务;
线程和进程的关系简单地说,进程是一个容器,一个进程中可以容纳若干个线程,就像我们一个公司比作一个进程,一个公司里面有几百名员工,那每个员工就是一个线程;
一个进程里面,至少有一个线程;

1.4如何查看进程下的线程及CPU占用率

1.4.1Window环境

windows下通过任务管理器就可以查看进程的cpu占用率,要查看线程的cpu占用率要借助其他工具,微软提供了 Process Explorer 工具可以查看;
下载地址:http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx
下载后解压,双击解压后的 procexp64.exe 文件运行即可;
查看线程属性,可能会弹出如下框,可以忽略;

1.4.2Linux环境

  • top
  • top -H -p pid

1.5下载JDK源码

  • http://jdk.java.net/
  • http://jdk.java.net/java-se-ri/8-MR3
  • https://download.java.net/openjdk/jdk8u41/ri/openjdk-8u41-src-b04-14_jan_2020.zip

1.6Java底层如何创建一个线程

  • Thread.c
  • jvm.h
  • jvm.cpp
  • thread.cpp
  • os_linux.cpp
    通过操作系统的 库函数 创建的线程,不是Java自己本身创建的;

1.7线程有哪些实现方式?

线程的实现方式主要有三种:

1、使用内核线程实现;

2、使用用户线程实现;

3、使用用户线程 + 内核线程混合实现;

1.7.1内核线程

内核线程(Kernel-Level Thread,KLT)就是直接由操作系统内核(Kernel)支持的线程,这种线程由操作系统内核来完成线程切换,操作系统内核通过操纵调度器(Scheduler)对线程进行调度,并负责将线程的任务映射到各个处理器上;

我们Java创建线程就是采用内核线程的方式创建的;

优点:一个线程阻塞,不影响另一个线程的执行;
缺点:
1、由于是基于内核线程实现的,所以各种线程操作,如创建、休眠及同步,都需要进行系统调用,而系统调用的代价相对较高;
2、操作系统内核支持的线程数量是有限的,不能无限制地创建线程;

1.7.2Linux系统能创建多少个Java线程?

  • /proc/sys/kernel/threads-max
    该文件表示内核所能使用的线程的最大数目;
  • linux 内核参数设置 - sysctl
  • sysctl?命令用于查看和修改内核参数
  • 查看指定参数: sysctl kernel.threads-max(或者cat /proc/sys/kernel/threads-max)
  • 查看所有参数: sysctl -a
  • 修改指定参数:?sysctl -w kernel.threads-max=102400
  • sysctl?设置的内核参数在?/proc/sys?目录下,格式为:?目录.文件
    比如:kernel.threads-max 对应目录 /proc/sys/kernel?下的 threads-max?文件;
    sysctl?的配置文件是:/etc/sysctl.conf
  • 在sysctl.conf?中设置的内核参数值,系统重启时会自动加载并设置;
    sysctl -p?让修改的sysctl.conf?配置文件生效;

1.7.3用户线程

  • 一般认为,一个线程只要不是内核线程,都可以认为是用户线程(User Thread,UT);
  • 用户线程指的是完全建立在用户自己的程序线程库上,系统内核不能感知到用户线程的存在及如何实现的。用户线程的创建、同步、销毁和调度完全在用户自己的程序代码中完成,不需要内核的帮助;
  • 优点:在用户自己的程序中实现,不需要调用内核,操作非常快速且低消耗,也能够支持规模更大的线程数量;
  • 缺点:由于没有系统内核的支援,所有的线程操作都需要由用户程序自己去处理,线程的创建、销毁、切换和调度都需要用户自己去实现,实现起来比- 较复杂;
  • 现在几乎百分之百的操作系统都支持多任务的执行(以前像dos操作系统是单线程的),在不支持多线程的操作系统中的多线程程序,那肯定需要自己来实现,还有一些需要支持大规模线程数量的应用,也可以考虑自己实现线程,否则的话都不倾向使用用户线程;
  • Java在1.2版本之前是自己实现线程,从1.2版本之后采用了内核线程;纤程(JDK17)
  • 但是近年来一些以高并发为卖点的编程语言又普遍支持了用户线程,譬如Golang、Erlang等;

1.7.4用户线程 + 内核线程混合实现

内核线程与用户线程一起使用的实现方式,既存在用户线程,也内核线程;

1.8再认识一下Java中的线程

  • 线程是Java程序执行的一条路径,每一个线程都有自己的虚拟机栈、程序计数器(指向正在执行的指令指针),当启动了一个Java虚拟机(JVM)时,从操作系统开始就会创建一个新的进程(JVM进程),JVM进程中将会派生或创建很多线程;

  • Java线程在早期的Classic虚拟机上(JDK 1.2以前),是基于一种被称为“绿色线程”(Green Threads)的用户线程实现的,但从JDK 1.3起,Java虚拟机的线程模型被替换为基于操作系统原生线程模型来实现,即内核线程实现,每一个Java线程都是直接映射到一个操作系统原生线程来实现的,JVM自己不会去干涉线程调度,可以设置线程优先级给操作系统提供调度建议,线程的调度全权交给底层的操作系统去处理,何时冻结或唤醒线程、给线程分配多少处理器执行时间、把线程分配给哪个处理器核心去执行等,都是由操作系统来调度完成的;

1.9在Java中创建线程的几种方式

1、Class Thread
2、Interface Runnable
3、Interface Callable
4、Executor
5、ThreadPoolTaskExecutor(Spring)

【衔接下一章 【并发编程二:Therad-api和main线程和子线程的关系】】

【并发编程一:走进并发编程】相关推荐

  1. java并发编程一:基础知识

    一.线程安全性 1.1 什么是线程安全性? 当多个线程访问某个类时,不管运行时环境采用何种调度方式或者这些线程将如何交替执行,并且在主调代码中不需要任何额外的同步或者协同,这个类都能表现出正确行为. ...

  2. futuretask java_Java并发编程一(FutureTask)

    一.前言 创建线程有几种方式? 继承 Thread 类 实现 Runnable 接口 但这两种方式创建的线程是属于"三无产品": 没有参数 没有返回值 没办法抛出异常 用着 &qu ...

  3. python电路模型编程_14、python开发之路-并发编程之I/O模型

    十四.并发编程之I/O模型 http://www.cnblogs.com/linhaifeng/articles/7454717.html 1.模型介绍 1.1 IO种类 (1)* blocking ...

  4. Java 并发编程之美:并发编程高级篇之一-chat

    借用 Java 并发编程实践中的话:编写正确的程序并不容易,而编写正常的并发程序就更难了.相比于顺序执行的情况,多线程的线程安全问题是微妙而且出乎意料的,因为在没有进行适当同步的情况下多线程中各个操作 ...

  5. Java 并发编程之美:并发编程高级篇之一

    借用 Java 并发编程实践中的话:编写正确的程序并不容易,而编写正常的并发程序就更难了.相比于顺序执行的情况,多线程的线程安全问题是微妙而且出乎意料的,因为在没有进行适当同步的情况下多线程中各个操作 ...

  6. java线程安全的set_Java并发编程之set集合的线程安全类你知道吗

    Java并发编程之-set集合的线程安全类 Java中set集合怎么保证线程安全,这种方式你知道吗? 在Java中set集合是 本篇是<凯哥(凯哥并发编程学习>系列之<并发集合系列& ...

  7. java并发编程之4——Java锁分解锁分段技术

    转载自 java并发编程之4--Java锁分解锁分段技术 并发编程的所有问题,最后都转换成了,"有状态bean"的状态的同步与互斥修改问题.而最后提出的解决"有状态bea ...

  8. java 时间戳_Java并发编程之CAS三CAS的缺点 及解决办法

    Java并发编程之CAS第三篇-CAS的缺点 通过前两篇的文章介绍,我们知道了CAS是什么以及查看源码了解CAS原理.那么在多线程并发环境中,的缺点是什么呢?这篇文章我们就来讨论讨论 本篇是<凯 ...

  9. 并发编程之LockSupport的 park 方法及线程中断响应

    系列文章目录 Java并发编程技术知识点梳理(第一篇)操作系统底层工作的整体认识 Java并发编程技术知识点梳理(第二篇)并发编程之JMM&volatile详解 Java并发编程技术知识点梳理 ...

最新文章

  1. Flutter开发之PageView指示器(31)
  2. python生成器函数_【python】生成器和生成器函数
  3. Matlab 工具箱
  4. 9-3:C++多态之多态的实现原理之虚函数表,虚函数表指针静态绑定和动态绑定
  5. (转)机器学习算法比较
  6. 中科软java笔试题
  7. Unity 编辑器下控制播放粒子
  8. android wear已停止运行,魔百盒显示“很抱歉CMCCWiMo已停止运行解决方法
  9. spring-kafka源码解析
  10. SVN Commit failed(details follow)
  11. 跨模态检索 | Visual Representation Learning
  12. SSH-keygen linux教程
  13. 对待Petya勒索病毒的解决办法
  14. proftpd服务器搭建
  15. vue项目中使用地址选择插件v-distpicker,省市区三级联动选择
  16. 2020CCPC绵阳站 Defuse the Bombs(简单二分)
  17. python文件查重工具,基于文件大小和md5/sha1值
  18. USCD行人异常数据集使用指南 | 快速下载
  19. hdu6082 度度熊与邪恶大魔王
  20. 囚徒困境困境_所以你现在看到了社会困境

热门文章

  1. java gc内存_Java内存模型和GC机制
  2. 计算机网络实验 ppt,计算机网络实验实验四跨交换机实现vlan.ppt
  3. 万德L2接口是什么?
  4. 各大搜索引擎蜘蛛IP地址大全
  5. 论企业上云的三大阻力!
  6. 项目管理PMP好考吗,没有经验?
  7. 被巨头、快递、新贵分食的跨境电商
  8. [BZOJ4537][Hnoi2016]最小公倍数(并查集+分块)
  9. c语言求出现次数最多的字符,保证你看懂
  10. Oracle和MySQL不同编码格式下varchar所能存储的中文数量