能够将Java并发编程抽象为三个核心问题:分工、同步和互斥。
这三个问题的产生源自对性能的需求。最初时,为提升计算机的效率,当IO在等待时不让CPU空闲,因而就出现了分时操做系统也就出现了并发。后来,多核CPU出现,不一样的任务能够同时独立运行,因而就出现了并行【分工】。有了分工后,效率获得了很大的提高,可是为了更合理的安排以及控制任务的进行,就须要让进程之间能够通讯【同步】,让彼此知道进度的执行。分工进行提升了效率,可是却带来了多线程访问共享资源会冲突的问题。因而对共享资源的访问又须要串行化。因此,依据现实世界的作法设计了锁等机制来使得多线程【互斥】访问共享资源。算法
分工的主要工做是:如何高效拆解任务并分配给线程。 编程
Java SDK并发包中的Executor
、Fork/Join
、Future
本质上都是分工方法。
并发编程中的一些设计模型也是指导如何分工:生产者——消费者
、Thread-Per-Message
、Work Thread
等。缓存
在并发编程的同步,主要指的就是线程间的协做。即当一个线程执行完了,该如何通知后续任务的线程展开工做。安全
协做通常和分工相关。Java SDK中Executor
、Fork/Join
、Future
本质上是分工方法可是也解决线程之间的协做问题(如Future异步调用,get())。Java SDK里提供的CountDownLatch
、CyclicBarrier
、Phaser
、Exchanger
也是用于解决线程之间的协做问题。多线程
线程协做问题均可以被描述为:当某个条件不知足时,线程须要等待,当某个条件知足使,线程须要被唤醒执行。并发
互斥指的是:在同一时刻,只容许一个线程访问共享变量。异步
由于 可见性、有序性和原子性(后面会有文章介绍)问题,多个线程访问同一个共享变量会致使结果的不肯定 。
为了解决这三个问题,Java语言引入了内存模型,内存模型提供了一系列的规则,利用这些规则咱们能够避免可见性问题、有序性问题,可是还不能彻底解决线程安全问题。性能
解决线程安全问题的核心方案仍是互斥。学习
实现互斥的核心技术就是锁。 Java语言中synchronized
、SDK中的各类Lock均可以解决互斥问题,可是锁却会带来性能问题,因而咱们就须要平衡。优化
主要方案有:分场景优化,优化读多写少场景:ReadWriteLock
、StampledLock
以及无锁结构Java SDK中的原子类;其余方案,原理为不共享变量或者变量只容许读,Java中提供了Thread Local
和Final
关键字和Copy-on-write
模式。
在看极客时间专栏《Java并发编程实战》学习攻略时,感触仍是比较深。平时学习知识都是“独立”的,没有一种“全局”观念,也不多联系其余一些理论来侧面验证学习的知识,致使学事后就很容易忘记。看了这篇专栏前言后,总结出:学习知识时,要跳出来看全景,钻进去看本质。要知道每一种技术背后都应该有理论支持,而且这个理论多是跨领域的,因此,掌握技术背后的理论十分很重要!
针对Java并发编程应该要结合操做系统一块儿来学习,如后面将要介绍的可见性、有序性和原子性。理解可见性就须要了解CPU和缓存的知识;理解原子性就须要理解操做系统的知识;不少无锁算法也是和CPU缓存有关。要联系起CPU、内存、I/O之间的关系。
参考: [1]极客时间专栏王宝令《Java并发编程实战》