0%

Java并发编程入门

前言

这篇文章其实是我很久之前总结的,因为之前的笔记都比较零碎,现在统一将他迁移到博客。学习Java并发编程强烈推荐两本书,一本是《Java并发编程实战》,另一本是《Java7 并发实战手册》

第一本书的作者里面有 Joshua Bloch ,这位大牛可是Java Current类库的作者之一哦,类库作者亲手写的书就足够成为你看它的理由啦。Anyway,这本书对并发的理论真的讲得很好,从竞态条件、原子性到内存逸出、乐观锁、悲观锁,内容十分全面,我觉得是每一个Java程序必读的书目,可以帮助你系统地学习Java并发的知识。

Java并发编程实战固然好,但是对于计算机基础薄弱的人来说,很多概念还是略显苦涩。如果你是这样的人的话,不妨先读一下Java7并发编程实战手册。Cook Cook Book嘛,跟着敲代码就行了,另外书中还会介绍一下并发的场景,都是对于新手很友好的哦~

基本概念

进程是资源分配(内存、文件描述符)的基本单位,线程是轻量级的进程,线程拥有独立的PC和栈,但是共享同一进程的资源,线程是系统调度的基本单位。其实在本质上,线程是把进程的资源分配和调度执行两个属性分割,进程仅仅拥有资源,线程共享进程资源并且成为处理机调度的基本单位,从而提高并发性。

注意:如果是单核处理器,一般单线程的执行效率会比多线程高,因为线程的调度存在上下文切换需要额外的时间。但是线程在多核上,多线程优于单线程,因为能够充分利用多个处理单位。

进程通信的机制

  1. 管道
  2. 共享内存
  3. 消息队列
  4. socket

进程的状态管理

就绪、运行、挂起、阻塞、结束

多线程编程的优缺点

优点:

  1. 很简单地就能实现异步。
  2. 能够充分利用多个处理器。
  3. 提供交互的高响应。

缺点:

  1. 安全性。竞态条件:当多个线程访问共享资源时,如果没有同步,会造成结果不正确。
  2. 活跃性。实现得不好可能会出现饥饿、死锁、活锁等情况。
  3. 性能。主要是线程调度会带来上下文切换的开销。

线程安全

本质是管理共享(可以被多个线程访问)、可变(在其生命周期内会发生改变)的状态。

线程安全的类:在任意调度、交替执行且无同步和协调的情况下,类的行为能保持正确。

原子操作:要么不执行,要么执行完,操作过程中不会被调度。

组合操作。

可重入锁:同一个线程申请锁时,计数器加一,可以进入临界区。

锁:sychronized Java内部锁。

共享对象

可见性:任意一个线程的修改都能作用于其他线程,不会出现过期的数据。也就是说当A线程修改了某一共享变量的值时,B线程总能读到最新的值。

加锁可以保证可见性和原子性。

volatile关键字:保证修饰的变量是可见的。一般满足以下几种情况可以使用:

  1. 除了可见性外,没有其他原因需要加锁。
  2. 写入变量事不依赖之前的状态 。
  3. 不需要和其他变量参与不变性约束。

发布和逸出
发布:使得一个对象能被当前范围外的代码访问。
逸出:一个对象尚未准备好时就将它发布。

比如匿名内部类this指针逸出,public方法逸出private域

线程封闭

  1. 使用一个线程
  2. 栈中的内容
  3. 使用ThreadLocal

不可变的对象永远是安全的。

线程概念

1.创建线程、运行线程、输出线程的相关信息。
2.线程和线程组、守护线程、线程的异常处理器
3.线程睡眠、线程让步、线程等待、线程中断以及线程中断的判断和处理。

编程案例

  1. 一个仓库,设置初始化容量。创建入库线程和出库线程,并发访问仓库容量。创建显示线程,实时输出仓库信息。
  2. 两个屏幕、两个售票处的电影院,每个电影院的票数独立,一个电影院的票不能用于两外一个电影院。
  3. 一个博物馆,设置参观人数的上限,当有人参观的时候,不能进行打扫,可以继续进来参观。当到达上限时,不能进入。当有人打扫时,不能有人进来参观。
  4. 一条东西向的单向马路,如果有向东的车辆行驶时,向西的车辆不能行驶,但向东的车辆可以行驶,反而亦然。
  5. 哲学家进餐问题。
  6. 打印机打印,同时只能有一个线程在打印。(多个打印机的情况)
  7. 视频会议,等待所有人到场后再开会。(重新准备,回退)
  8. 三个线程、读取三个文件夹及其子文件夹中的文件,查找24小时内被修改过的文件后缀为.txt的文件。

附加属性

  1. 公平性。等待越久的线程,优先被调度。

后记

先占着个坑啦后面如果使用较多的方面再慢慢补充