Java Concurrent Programming

现在的很多应用场景,比如需要提高并发,提高处理能力、效率,加快处理速度等等。而很多人一面对这种问题就会想到分布式解决方案,想到用hadoop。但是有的场景下,只需要用java并发编程就能解决问题。那java并发到底改怎么做,能够处理哪些需求呢?那我们就来一起学习一下java并发编程。

一、基础知识

我们需要了解一些关于并发编程的基础知识

1. 了解自己的CPU

要做并发编程,首先我们得了解我们的机器是否支持多线程,能够支持多少并行线程。当然,决定性的关键在于机器的CPU。

我们知道,在现在的各类CPU都是多核多线程CPU。那我们该怎么看这个CPU对并发的支持度有多少呢?举个例子。假如我们有个PC,CPU是双核双线程(Intel的超线程技术可使核:线程数=1:2)。那也就是说我们有2*2条通道。可以想象成我们有四条车道,每条车道都能跑,也就是支持四个线程同时运行。当然,服务器的CPU更多核,更多线程。

那怎么查看自己的CPU是几核几线程的呢?Linux当然是在/proc/cpuinfo下查看,windows用设备管理器查看,也可以用鲁大师之类的查看。

point: 通过查看CPU信息,支持并行线程数=核心数*单个核支持的线程数

2. 线程和进程的区别

线程和进程在本科期间的操作系统课就有学。先给一个定义:进程是程序运行资源分配的最小单位,线程CPU调度的最小单位。可能看完这个定义,你跟我一样还是有点懵。没关系,咱们再解释一下。

打个比方:我们把计算机比作一间仓库。仓库里有很多箱子。每个箱子里装着不同种类和数量的小动物,比如说小狗啊,鱼啊,小猫啊(当然他们都是活的,一个箱子有任意个小动物)。我们就把进程比作这一个个箱子。把线程比作箱子里面的小动物。

在仓库里,我们要存放小动物,我们需要以箱子为单位给他们提供空间(不能让他们满仓库乱跑吖),箱子里有各类小动物需要的资源,比如水,食物等等。一个箱子里的小动物(线程)可以共享这些资源。但是可以动的(运行)就是这一个个小动物,就是最小的运行单位了。

进程和线程的区别差不多就是这个比喻这样,进程之间相互独立。进程是具有一定独立功能的程序关于某个数据集合上的一个运行活动,是资源分配和调度的独立单位。线程是进程的一个实体,是CPU调度和分派的基本单位,比进程更小,能独立运行。同属于一个进程内的线程共享资源。

3. 并行与并发

并行与并发经常容易搞混淆。我们说的是并行编程,为什么不说并发编程捏?什么是并行,什么是并发?

还是打个比方。一条高速公路,有8车道。如果你8个车道同时开通车(线程),同时开的车数量小于等于8,即每条车道一辆车,这几辆实实在在的在同时开动,那么就是并行

并发的意思就是虽然只有8个车道,但是你往车道上放了大于8台车,要一起开动,那也就以为着你需要做调度,安排一下这些车怎么运行。这就是并发

point: 同时运行的线程数 > CPU支持的并行数,则是并发,否则并行。

4. 并发量和吞吐量

并发量

我们在做并发编程的时候,需要计算一下支持的并发量到底是多少。怎么算呢?并发量的计算需要考虑到很多因素,比如程序占用的带宽、程序占用的内存、CPU调度时间等等。有很多计算方法,这里只给出极限并发量算法,即理想状态,不考虑其他因素时并发量的支持度。

假如一台服务器2个CPU,每个CPU8核16线程,那一秒内,极限并发量的计算为

(1000ms* 2 * 8 * 16)/(CPU切片轮换时间(假如10ms)+程序执行时间(假如10ms))=1600个并发。

如果前台不死机,客户最大容忍3s,则这套程序支持的最大并发量为3*1600=4800个并发访问。

吞吐量

吞吐量指对网络、设备、端口、虚电路等设施,在单位时间内成功传输的最大数据量。这里要和带宽区分一下。带宽是在通信链路中,以太网链路支持的最大传输量,但是你的系统中还有其他设施啊,比如接口啊,路由器等等,这些的吞吐量不够的话,整体系统的吞吐量是会减小的,也就是要看吞吐量瓶颈在哪儿,是多少来决定系统的吞吐量

这里大概就是一些基础知识,我们需要知道分布式、并行、并发的区别,才能正确去运用他们。ok,这一章就酱。