文章目录
- 并发编程的三个核心问题
- 参考
并发编程的三个核心问题
并发编程可以总结为三个核心问题:分工、同步、互斥。
所谓分工指的是如何高效地拆解任务并分配给线程,而同步指的是线程之间如何协作,互斥则是保证同一时刻只允许一个线程访问共享资源。java SDK并发包很大部分内容都是按照这三个维度组织的 ,例如Fork/Join框架就是一种分工模式,CountDownLatch就是一种典型的同步方式,而可重入锁则是一种互斥手段。
-
分工(性能)
分工的主要工作是:如何高效拆解任务并分配给线程。
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 SDK并发包里的Executor、Fork/Join、Future本质上都是分工方法,但同时也能解决线程协作的问题。例如,用Future可以发起一个异步调用,当主线程通过get()方法取结果时,主线程就会等待,当异步执行的结果返回时,get()方法就自动返回了。**主线程和异步线程之间的协作,Future工具类已经帮我们解决了。**除此之外,Java SDK里提供的CountDownLatch、CyclicBarrier、Phaser、Exchanger也都是用来解决线程协作的问题。
-
互斥
分工、同步主要强调的是性能,但并发程序里还有一部分是关于正确性的,用专业术语叫“线程安全”。并发程序里,当多个线程同时访问一个共享变量时,结果时不确定的。不确定,则意味着可能正确,也可能错误,事先是不知道的。而导致不确定的主要源头是可见性的问题、有序性问题和原子性问题,为了解决这三个问题,Java语言引入了内存模型,内存模型提供了一系列的规则,利用这些规则,我们可以避免可见性问题、有序性问题,但是还不足以完全解决线程安全问题。解决线程安全问题的核心方案还是互斥。
所谓互斥,指的是同一时刻,只允许一个线程访问共享变量。
实现互斥的核心技术就是锁,Java语言里synchronized、SDK里的各种Lock都能解决互斥问题。虽说锁解决了安全性问题,但同时也带来了性能问题,那如何保证安全性的同时又尽量提高性能呢?可以分场景优化,Java SDK里提供的ReadWriteLock、StampedLock就可以优化读多写少场景下锁的性能。还可以使用无锁的数据结构,例如Java SDK里提供的原子类都是基于无锁技术实现的。
总结: 分工是设计,同步和互斥是实现。
参考
学并发编程,透彻理解这三个核心是关键
参考URL: https://www.sohu.com/a/375273562_753508
简述并发编程分为三个核心问题:分工、同步、互斥。
参考URL: http://www.520mwx.com/view/70439
【Java并发基础】并发编程领域的三个问题:分工、协作和同步
参考URL: https://www.cnblogs.com/myworld7/p/12189332.html