《Java Concurrency in Practice》是于2006年出版,由Brian Goetz等人合著的一本经典的Java并发编程指南。该书详细介绍了Java平台上的并发编程概念、技术和最佳实践。它提供了丰富的实例和案例研究,帮助开发人员理解和解决并发编程中的常见问题。至今仍然被广泛认可为Java并发编程领域的经典参考书籍之一。
让我们看看17年前的前辈们对并发的理解与实践。
在preface这里大概描述了这本书的由来,因许多工程师随着并发量的提高,从而不断涌现出bug,在2004年java发布java.util.concurrent包,并在2006年针对并发问题,著作了这本书。
At this writing, multicore processors are just now becoming inexpensive enough for midrange desktop systems. Not coincidentally, many development teams are noticing more and more threading-related bug reports in their projects. In a recent post on the NetBeans developer site, one of the core maintainers observed that a single class had been patched over 14 times to fix threading-related problems. Dion Almaer, former editor of TheServerSide, recently blogged (after a painful debugging session that ultimately revealed a threading bug) that most Java programs are so rife with concurrency bugs that they work only “by accident”.
越来越多的开发团队在项目中遇到与线程相关的错误报告。
这导致开发、测试和调试多线程程序变得异常困难,因为并发错误往往无法可预测地显现,而且往往在最糟糕的时候出现,比如在生产环境下、在负载较重时。
大多数 Java 程序都充斥着并发 bug,它们仅仅是“碰巧”可以工作。
Indeed, developing, testing and debugging multithreaded programs can be extremely difficult because concurrency bugs do not manifest themselves predictably. And when they do surface, it is often at the worst possible time—in production, under heavy load.
由于并发性的 bug 不会以可预见的方式自己“蹦”出来,因此多线程程序的开发、测试和调试都会变得极端困难。bug 浮出水面的时刻,通常可能是最坏的时候一一对应于生产环境,就是指在高负载的时候。
One of the challenges of developing concurrent programs in Java is the mismatch between the concurrency features offered by the platform and how developers need to think about concurrency in their programs. The language provides low-level mechanisms such as synchronization and condition waits, but these mechanisms must be used consistently to implement application-level protocols or policies. Without such policies, it is all too easy to create programs that compile and appear to work but are nevertheless broken. Many otherwise excellent books on concurrency fall short of their goal by focusing excessively on low-level mechanisms and APIs rather than design-level policies and patterns.
使用Java 开发并发程序所要面对的挑战之一,是要面对平台提供的各种并发特性之间的不匹配,还有就是程序员在他们的程序中应该如何思考并发性。语言提供了一些低层机制,比如同步和条件等待,但是这些机制在实现应用级的协议与策略时才是必须的。不顾这些策略的约束,很容易创建出一个程序,它在编译和运行时看上去一切正常,不过这其中却存在隐患。很多并发方面相当不错的书都没能达到预期的目标,它们过分地关注于低层的机制和API,而不是设计层面的策略和模式。
Java 5.0 is a huge step forward for the development of concurrent applications in Java, providing new higher-level components and additional low-level mechanisms that make it easier for novices and experts alike to build concurrent applications. The authors are the primary members of the JCP Expert Group that created these facilities; in addition to describing their behavior and features, we present the underlying design patterns and anticipated usage scenarios that motivated their inclusion in the platform libraries.
Our goal is to give readers a set of design rules and mental models that make it easier—and more fun—to build correct, performant concurrent classes and applications in Java.
We hope you enjoy Java Concurrency in Practice.
Brian Goetz
Williston, VT
March 2006
Java 5.0 是在使用Java 开发并发应用程序的进程中,迈出的巨大一步。它提供了新的高层组件以及更多的低层机制,这些将使得一名新手更容易像专家那样去构建并发应用程序。本书的作者都是JCP 专家组的主要成员,正是这个专家组创建了这些新工具:除了去描述新工具的行为和特性,我们还向您展示了它们低层的设计模式,预期的使用场景以及将它们纳入平台核心库的动机。
我们的目标是给读者一些设计法则和理念模型,让读者在使用 Java 构建正确、高效的并发类和应用程序时,变得更容易、更有趣。
在网上说java.util.concurrent的很多,在什么时候引入就很少介绍, 后面我自己在外网搜了下。
Java的并发工具包(java.util.concurrent)是在Java 5版本中引入的。
Java 5发布于2004年,它引入了许多新的语言特性和库,其中包括了用于并发编程的java.util.concurrent包。
java.util.concurrent包提供了一组并发编程工具和类,用于简化多线程编程和管理并发任务。它包含了诸如线程池(ThreadPoolExecutor)、并发集合(ConcurrentHashMap、ConcurrentLinkedQueue等)、原子变量(AtomicInteger、AtomicLong等)、倒计时门闩(CountDownLatch)等常用的并发构件。这些工具和类的引入使得开发人员能够更方便地编写高效且线程安全的并发代码。
Java的并发工具包的引入极大地改善了并发编程的可用性和可靠性,提供了更高级别的抽象和更强大的工具,使开发人员能够更好地处理并发编程的挑战。这也为后续的Java版本奠定了并发编程的基础,并成为开发高性能和可伸缩性应用程序的重要工具之一。
在java5 之后一些并发编程方面的重要更新
作者回顾了计算机行业的发展历程,从早期的单核处理器到现在的多核处理器,解释了为什么并发编程成为当代软件开发的重要议题。
作者提到早期的计算机系统中通常只有一个处理器,因此并发编程并不是一个主要的关注点。然而,随着处理器技术的发展和硬件成本的下降,多核处理器变得越来越普及,使得并发编程成为必要的技能。
作者还提到,并发编程的出现是为了充分利用多核处理器的性能,并发编程的目标是使程序能够同时执行多个任务,并充分利用系统资源。
本节着重强调了使用线程进行并发编程的益处,并介绍了几个与线程相关的优势。
首先,使用线程可以提高程序的响应性。通过将任务分配给不同的线程并同时执行,程序可以更快地响应用户的请求,提供更好的用户体验。
其次,线程可以提高系统的吞吐量。通过并行处理多个任务,系统能够同时执行多个操作,从而提高整体处理能力。
此外,线程还可以更好地利用多核处理器的资源。在多核系统中,使用线程可以充分利用每个核心的处理能力,提高系统的性能。
本节还提到了一些其他的线程优势,例如更好的资源利用、更容易的任务管理和更高的可扩展性。
在这节中,提到了synchronous I/O, nonblocking I/O 和 multiplexed I/O(多路复用)。
In a single-threaded application, this means that not only does processing the corresponding request stall, but processing of all requests stalls while the single thread is blocked. To avoid this problem, singlethreaded server applications are forced to use nonblocking I/O, which is far more complicated and error-prone than synchronous I/O.
作者提到在单线程应用中,意味着不仅处理对应请求停止了,处理所有的请求都停止了,当单线程被锁住的时候。而避免这个问题,单线程应用 被迫使用的 非锁住的IO流,这个更复杂和更容易出错 对比同步IO流。
However, if each request has its own thread, then blocking does not affect the processing of other requests.
这里最后提到的每个请求拥有自己的线程的模型是一种常见的处理方式,被称为(one-thread-per-request)模型。在这种模型中,每个请求都会被分配一个独立的线程进行处理,不同请求之间的处理互不影响。如果一个请求发生阻塞,只会影响到该请求对应的线程,而不会影响其他请求的处理。
然而,随着应用程序规模的增大和并发需求的增加,使用"one-thread-per-request"的模型可能会导致线程数量过多,占用大量系统资源,同时线程切换的开销也会增加。这种模型在高并发情况下可能面临线程资源耗尽、上下文切换开销过大等问题。
现代的并发编程模型和框架通常采用了更高效的方式来处理请求,如使用线程池来重用线程、使用异步非阻塞的I/O模型等。这样可以更好地利用系统资源,减少线程创建和销毁的开销,提高并发处理能力。
因此,现在的实践中,不一定每个请求都有自己的线程。相反,更常见的做法是使用线程池来管理一定数量的线程,通过线程池来处理请求。这样可以更好地控制线程的数量,避免线程过多导致的资源浪费,并且通过异步非阻塞的方式处理I/O操作,提高系统的并发性能。
后面,针对
主要写了线程带来的风险和挑战,包括以下几个方面:
这章也会在后面着重讲解,对并发编程来说非常重要。
这一章节主要强调了线程在现代计算中的普遍存在性和重要性。
总的来说,本章强调了线程在现代计算中的普遍应用,并指出了并发编程所面临的挑战和发展趋势。了解并掌握并发编程的原理和技术对于开发高性能和可靠的软件系统至关重要。
该书详细介绍了Java平台上的并发编程概念、技术和最佳实践。它提供了丰富的实例和案例研究,帮助开发人员理解和解决并发编程中的常见问题。
该书的内容主要分为四个部分:
《Java Concurrency in Practice》被广泛认为是学习和实践Java并发编程的权威参考。它提供了全面而深入的内容,涵盖了从基础知识到高级技术的方方面面。无论是初学者还是有经验的Java开发人员,都可以从中获得宝贵的知识和实践经验,从而提升自己在并发编程领域的能力。
Copyright © 2023 leiyu.cn. All Rights Reserved. 磊宇云计算 版权所有 许可证编号:B1-20233142/B2-20230630 山东磊宇云计算有限公司 鲁ICP备2020045424号
磊宇云计算致力于以最 “绿色节能” 的方式,让每一位上云的客户成为全球绿色节能和降低碳排放的贡献者