Java并发和多线程指导综述
原文地址:http://tutorials.jenkov.com/java-concurrency/index.html
java并发是java平台世界的一个述语,它意味着多线程、并发和并行,其中包括java并发工具,以及可能遇到的问题和解决方案。Java并发指导会涉及到多线程、并发结构、并发问题、代价和多线程的好处等等一系列概念。
并发的简史
在过去,一台计算机还只有一个CPU,所以在同一时间就只能执行一个程序。随着多任务概念的出现,但其并不是真正意义上的多任务,只是号称可以在同一时刻执行多个任务,而其本质是多个任务之间共享单一CPU。CPU会根据时间片在多个任务之间切换并执行,而这个过程由操作系统来控制。
而多任务概念的出现给软件开发者带来了新的挑战。也就是说,应用程序再也不能占用计算机的全量CPU时间,全部的可用内存以及其他的计算机资源。一个好的程序应该是在它不再使用资源的时候释放掉自己占用的全部资源,从而给其他程序使用。
近来的多线程意味着在同一个程序内部你可以有多个线程来执行任务。一个线程的执行可以被认为是一个CPU在执行程序。当你有多个线程在执行的时候,就好像有多个CPU在同一程序内执行。
多线程的出现给一些类型的程序提供了一条提高性能的出路。然而,多线程相比多任务有更多的挑战。多个线程在同一程序内执行,可能会出现同时读取某一内存资源的情况。这种情况可能会出现错误,而这种错误在单线程应用内永远不会出现。其中的部分错误在单一CPU的机器上也可能不会出现,因为两个线程永远不可能真正的"同时执行"。随着计算机的现代化,多核CPU出现,也就是多处理器。这就是说,独立的线程可以在同一时刻在独立的CPU上同时执行。
示意图如下:
如果一个线程读取的内存地址刚好是另外一个线程在写的地址,那么第一个线程最后读取到的究竟是什么值呢?是原来存储的值?还是第二个线程写入的新值?又或者是一个混合了新旧值的一个值(部分位的值是旧值,部分位的值是新值)?当然如果有两个线程同时在写相同内存地址,那么当操作完成后,当前内存地址中存储的值会是什么呢?是第一个线程的值?好是第二个线程写入的值?还是混合值呢?这个估计只有计算机自己才能知道。
如果不采取合适的错误,那么上述的三种情况都是有可能的。而且这种值是不可预测的。这个结果可能每次都不一样。所以,对于一个开发来说,知道如何正确预防上述情况的发生,就显得特别重要,这也就是说,能够控制线程如何访问共享资源,比方说内存地址、文件、数据库资源等等。这是java并发指导要讨论的主题之一。
java世界的多线程和并发
java是第一批支持开人员容易书写多线程开发的语言之一。Java语言从一开始就有多线程能力。因此,java开发者总是会面对上述所说的问题。这也是我为啥要写这个指导的原因。不仅仅是我自己,希望所有java开发者都可以从中受益。
该指导内容主要关注于java中的多线程,但一些问题同样也会发生在多任务和分布式系统中。所以多任务和分布式系统中的一些问题也可以参考该指导。简单来说,并发不仅仅是多线程。
Java并发在2015和未来
自从第一本java并发书出版以来,在并发世界里的结构和设计都发生了很大的变化,当然java5也发布了独立的并发包内容。
全新的平台出现,异步无共享平台和像Vert.x and Play / Akka and Qbit 的APIs,这些平台使用了新的并发模型标准,不同于java/JEE并发模型(多线程,共享内存和锁)。新的非阻塞并发算法也已经发布,而且新的非阻塞工也已经加入了我们的工具及中,像LMax Disrupter 。新的并发函数式编程也在JAVA7的Fork and Join结构中有所介绍,而且JAVA8给出了流集合的API。
随着这些新东西的发布,也是时候更新一下这个并发指导了,因此,这个指导再次开始编写。新的指导会实时发布。
Java并发指导的学习
如果你还不了解java并发,我推荐你跟着下面的学习计划学习,你能通过连接找到所有主题。
- 多线程的好处
- 多线程的代价
- 并发模型
- 同一线程
- 并发VS并行
java并发的基础:
- 创建和开启java线程
- 竞态条件和临界资源
- 线程安全和共享资源
- 线程安全和枚举
- java内存模型
- java同步阻塞
- java关键字之Volatile
- java的ThreadLocal
- java的Thread Signaling
java并发的典型问题:
- 死锁
- 死锁语法
- 饥饿和公平
- 嵌套管程死锁
- 限制条件
能够帮助解决上诉问题的的java并发结构:
- java中的锁
- java中的读写锁
- 可重入锁
- 信号量
- 阻塞队列
- 线程池
- 比较并且交换
未来的主题:
- 同步器的详解
- 非阻塞算法
- Amdahl's Law的详解
- 引用