第一部分 线程并发基础
文章目录
第一章 概念部分
1.CPU核心数、线程数
- CPU位宽:能够处理的数据运算范围和支持的内存容量;
32位CPU只支持4GB以内的内存 - 多核心、多线程:一般情况下,一个核心对应一个线程,但是Intel引入超线程技术后,可使一个核心对应两个线程;
多核心,集成多个处理器至同一芯片,并行执行不同进程;多线程,操作系统通过线程来执行任务。
2.CPU时间片轮转机制
- 时间片、进程切:时间片是允许某一个进程运行的时间;进程切,从一个进程切换至另一个进程。
时间片设置的太短会导致过多的进程切换,降低了CPU效率;而设的太长又可能引起对短的交互请求的响应变差。
3.进程和线程
- 进程:程序运行资源分配的最小单位
- 线程:CPU调度的最小单位
4.并行和并发
- 并行:运行中线程数<=CPU数量*CPU核心(线程)数量
- 并发:运行中线程数>=CPU数量*CPU核心(线程)数量
5.吞吐量
- 吞吐量:指对网络、设备、端口、虚电路或其他设备,单位时间内成功传送数据的数量。
- 网络吞吐量:某个时刻,网络中两个节点之间,提供给网络应用的剩余带宽。
- 系统吞吐量:一个时间段所处理的进程数来度量。
- 吞吐量、带宽:吞吐量是throughput,带宽是Max net bitrate。
6.高并发编程的优缺
- 优点:(1)充分利用CPU资源(2)加快响应用户的时间(3)使代码模块化、异步化、简单化
- 需注意:(1)线程之间的安全性,资源共享问题(2)线程之间的死循环,引入锁机制(3)线程太多导致服务器资源耗尽形成死机,资源池(线程池)如数据库连接池。
7.分布式、并行、并发
- 分布式:分配给多个计算机工作
- 并行:多核CPU
- 并发:多线程技术
8.Linux和Windows对并发采取的不同机制
- Linux:子进程概念
- Windows:一个进程下多线程并发
第二章 认识Java里面的Thread
1.线程简单实现的三种方法
- 直接extends Thread覆盖run()方法
- 实现Runnable接口,实现run()方法 (最常见)
- implements Callable,实现call()方法
2.Thread里面的属性和方法
3.关于线程的中断机制
4.线程的生命周期
- 线程生命周期的5种状态:新建(new Thread)、就绪(runnable)、运行(running)、阻塞(blocked)、死亡(dead)。
5.守护线程
- 守护线程:后台运行线程,如GC
6.线程组
- 线程组、线程池:ThreadGroup是为了方便线程管理出现的,system线程组是所有线程最顶级的父线程组,其下是main线程组。
线程组是为了方便线程的管理,而线程池是为了管理线程的生命周期、复用线程、减少创建销毁线程的开销。
第三章 Thread安全
1.初识Java内存模型与多线程
CPU在计算时,数据读取顺序优先级:寄存器》高速缓存》内存;
JMM(Java内存管理模型)规定了jvm有主内存和工作内存,主内存即是Java堆内存、工作内存即是每个线程私有的内存
可见性问题:单个线程与线程的工作内存之间有相互隔离的效果
时序性问题:read、load、use主内存中获取的变量副本还是直接引用原来的副本,操作的先后顺序,决定了程序对主内存区最后的修改是否正确。
2.线程不安全与安全
不安全:当多个线程同时操作一个数据结构的时候产生了相互修改和串行的情况,没有保证数据的一致性。
实现线程安全:(1)多实例,也就是不用单例模式(2)使用java.util.concurrent下面的类库(3)使用锁机制synchronized、lock方式
3.隐式锁与显示锁
- 隐式锁(线程同步):synchronized,当用它来修饰一个方法或者一个代码块的时候,能够保证同一时刻最多只有一个线程执行该段代码,即解决”时序性问题“
- 显示锁:Lock、ReentrantLock
4.死锁
- 死锁:在两段不同的逻辑都在等待对方的锁释放才能继续往下工作时,这个时候会产生死锁。
5.Java关键字volatile修饰变量
- volatile:易变的、不稳定的。这个关键字的作用是告诉编译器,凡是被其声明的变量都是易变、不稳定的。所以不要试图对该变量使用缓存等优化机制,而应当每次都从它的内存地址中去读取值。
对内存可见性要求高,而对原子性要求低的地方。 - volatile与加锁机制的区别:加锁机制既可以确保可见性又可以确保原子性;而volatile变量只有确保可见性。
6.原子操作:atomic
- atomic:不会阻塞线程,线程安全的加强版volatile原子操作。
第四章 线程安全的集合类
待续