thread

聊聊并发

  • 你真的了解并发码
  • 多线程和并发
  • 多线程和多进程
  • 线程一定快吗
  • 学习并发的四个阶段
  • 学习目标
  • 适合人群
  • 推荐推荐

简介

编写正确的程序很难,而编写正确的并发程序则难上加难。
与串行程序相比,在并发程序中存在更多容易出错的地方。那么,我们为什么还要编写并发程序呢?

线程是Java语言中不可或缺的重要功能,它们能使复杂的异步代码变得更简单,从而极大地简化了复杂系统的开发。
此外,使用线程可以充分发挥多处理器的强大计算能力。随着处理器数量的持续增长,如何高效地使用并发正变得越来越重要。

并发简史

早期的计算机不包含操作系统,在这种裸机环境中每次只能运行一个程序,浪费计算机资源。

操作系统的出现使得计算机每次能运行多个程序,不同的程序在单独的进程中运行,操作系统为各个独立的进程分配各种资源,包括
内存、文件句柄以及安全证书等。在不同的进程之间可以通过一些粗粒度的机制通信,包括:套接字、信号处理器、共享内存、信号量以及文件等。

线程允许在同一进程中同时存在多个程序控制流。线程会共享进程范围内的资源,例如内存句柄和文件句柄,
但每个线程都有自己的程序计数器(Program Counter)、栈以及局部变量等。
在同一个程序中的多个线程可以被同时调度到多个CPU 上运行。

线程也被称为轻量级进程。在大多数现代操作系统中,都是以线程为基本的调度单位,而不是进程。

由于同一个进程中的所有线程都将共享进程的内存地址空间,因此这些线程都能访问相同的变量并在同一个堆上分配对象。
这就需要实现一种比在进程间共享数据粒度更细的数据共享机制。如果没有明确的同步机制来协同对共享数据的访问,那么
当一个线程正在使用某个变量时,另一个线程可能同时修改这个变量,这将造成不可预测的结果。

线程的优势

  • 线程可以有效地降低程序的开发和维护成本,同时提升复杂应用程序的性能。
  • 线程能够将大部分异步工作流转换成串行工作流,因此能更好地模拟人类的工作方式和交互方式。
  • 降低代码的复杂度,使代码更容易编写、阅读和维护。
  • 在GUI应用程序中,线程提供用户界面的灵敏度。
  • 在服务器应用程序中,可以提升资源利用率以及系统吞吐率。
  • 简化JVM的实现,垃圾收集器通常在一个或多个专门的线程中运行。

线程带来的风险

  • 安全性问题
  • 活跃性问题
  • 性能问题

线程安全性是非常复杂的,在没有充足同步的情况下,多个线程中的操作执行顺序是不可预测的,甚至会产生奇怪的结果。
在下面的UnsafeSequence 类中将产生一个整数值序列,该序列中的每个值都是唯一的。

1
2
3
4
5
6
7
8
9
10
11
12
public class UnsafeSequence {

private int value;

/**
* 返回一个唯一的数值
* @return
*/
public int getValue() {
return value++;
}
}

在单线程环境中,这个类能正常工作,但是在多线程环境中则不能。
UnsafeSequence 问题在于,递增运算value++ 看上去是单个操作,实际上它包含三个独立的操作:
读取value,将value值加1,将计算结果写入value。由于运行时可能多个线程之间的操作交替执行,结果可能返回了相同值。

// 画图

这是一种常见的并发安全问题,称为竞态条件(Race Condition)。
要使多线程程序的行为可以预测,必须对共享变量的访问操作进行协同,防治多线程之间发生彼此干扰。
Java提供了各种同步机制来协同这种访问。通过将getValue 方法改为一个同步方法,可以修复UnsafeSequence 中的错误。

1
2
3
4
5
6
7
/**
* 返回一个唯一的数值
* @return
*/
public synchronized int getValue() {
return value++;
}

线程无处不在

Thread t1 = new Thread() {
@Overvide
public void run() {
}
};
t1 是指向Thread 实例的一个引用,并不是一个真正的线程。
t1.start();

1.Java程序的main方法是一个线程,是被JVM启动时候调用,线程的名字是main。
2.实现一个线程,必须创建Thread实例,Override run方法,并且调用start方法。
3.当

为什么要学习并发编程
并发优点:

  • 发挥出多处理器的能力
  • 建模的简单性
  • 异步事件的简化处理
  • 响应更加灵敏的用户界面

并发的缺点

  • 线程安全性问题
  • 活跃性问题
  • 性能问题

学习并发的四个阶段

  • 熟练掌握API,能够完成并发编程
  • 熟读API源码,掌握其原理
  • 理解Java虚拟机的内存模型
  • 操作系统对并发对支持
坚持原创技术分享,您的支持将鼓励我继续创作!