Java Concurrency in Practice读书笔记 ( 1 )

Java Concurrency in Practice

Chapter 1. Introduction

Writing correct programs is hard; writing correct concurrent programs is harder. There are simply more things that can go wrong in a concurrent program than in a sequential one. So, why do we bother with concurrency? Threads are an inescapable feature of the Java language, and they can simplify the development of complex systems by turning complicated asynchronous code into simpler straight-line code. In addition, threads are the easiest way to tap the computing power of multiprocessor systems. And, as processor counts increase, exploiting concurrency effectively will only become more important.

编写正确的程序是困难的;编写正确的并发程序更难。并发程序比顺序程序存在更多容易出错的地方,因此,为什么我们还关心并发呢?原因如下:线程是JAVA语言不可避免的特性,它们能够通过把复杂的异步代码简化为更为简单的顺序代码,从而简化复杂系统的开发和设计。另外,线程是实现多处理机的强大计算能力的最简易的方法,并且,随着处理器计算能力的与日俱增,如何有效探索并发变得越来越重要。

1.1.        A (Very) Brief History of Concurrency

一个关于并发的简明历史

In the ancient past, computers didn't have operating systems; they executed a single program from beginning to end, and that program had direct access to all the resources of the machine. Not only was it difficult to write programs that ran on the bare metal, but running only a single program at a time was an inefficient use of expensive and scarce computer resources.

在那个久远的年代,计算机并没有操作系统;从头到尾他们都执行一个单一的程序,而这个程序直接处理机器的所有资源。这样,不仅仅造成了编写在裸机上运行的程序十分困难,而且一个时刻运行一个单一的程序也是对珍贵的计算机资源的极大浪费。

Operating systems evolved to allow more than one program to run at once, running individual programs in processes: isolated, independently executing programs to which the operating system allocates resources such as memory, file handles, and security credentials. If they needed to, processes could communicate with one another through a variety of coarse-grained communication mechanisms: sockets, signal handlers, shared memory, semaphores, and files.

    操作系统的发展使得多个程序能同时运行在处理器中,操作系统负责把内存,文件句柄,安全认证等资源分配给独立的可执行程序。如果它们需要,操作系统还可以通过一系列粗糙的通信机制来让彼此通信:sockets, signal handlers, shared memory, semaphores, and files

Several motivating factors led to the development of operating systems that allowed multiple programs to execute simultaneously:

一些推进操作系统发展的因素使得多道程序能够同时执行:

Resource utilization. Programs sometimes have to wait for external operations such as input or output, and while waiting can do no useful work. It is more efficient to use that wait time to let another program run.

资源利用。程序有时会因外部事件譬如I/O而阻塞,阻塞期间并不能做有用的工作。在程序阻塞期间让另一个程序得以执行显然更为有效。

Fairness. Multiple users and programs may have equal claims on the machine's resources. It is preferable to let them share the computer via finer-grained time slicing than to let one program run to completion and then start another.

公平。多个用户和程序对系统资源有平等的要求。让程序通过finer-grained时间片分享系统资源好过让一个程序运行到底然后再开始另一个。

Convenience. It is often easier or more desirable to write several programs that each perform a single task and have them coordinate with each other as necessary than to write a single program that performs all the tasks.

便利性。编写多个程序,其中每个程序处理单个任务,然后让它们互相协作,通常来说这样做远比编写一个处理所有任务的单个程序更为简单可取。

In early timesharing systems, each process was a virtual von Neumann computer; it had a memory space storing both instructions and data, executing instructions sequentially according to the semantics of the machine language, and interacting with the outside world via the operating system through a set of I/O primitives. For each instruction executed there was a clearly defined "next instruction", and control flowed through the program according to the rules of the instruction set. Nearly all widely used programming languages today follow this sequential programming model, where the language specification clearly defines "what comes next" after a given action is executed.

在早期的分时系统中,每个处理器就是一个虚拟的冯诺依曼机;它有一个存储数据和指令的存储器,依赖机器语言的语义顺序执行指令,通过操作系统的一系列I/O原语与外界交互。每条指令执行完毕后有一个被清晰定义的“下一条指令”,控制程序按照指令集的规则往下执行。几乎今天所有被广泛使用的编程语言都是遵照这个顺序编程的模式,在这个模式中语言会清晰定义一条指令执行完毕后下一步怎么办。

The sequential programming model is intuitive and natural, as it models the way humans work: do one thing at a time, in sequence mostly. Get out of bed, put on your bathrobe, go downstairs and start the tea. As in programming languages, each of these real-world actions is an abstraction for a sequence of finer-grained actionsopen the cupboard, select a flavor of tea, measure some tea into the pot, see if there's enough water in the teakettle, if not put some more water in, set it on the stove, turn the stove on, wait for the water to boil, and so on. This last step waiting for the water to boil also involves a degree of asynchrony. While the water is heating, you have a choice of what to do just wait, or do other tasks in that time such as starting the toast (another asynchronous task) or fetching the newspaper, while remaining aware that your attention will soon be needed by the teakettle. The manufacturers of teakettles and toasters know their products are often used in an asynchronous manner, so they raise an audible signal when they complete their task. Finding the right balance of sequentiality and asynchrony is often a characteristic of efficient people and the same is true of programs.

顺序编程模式是直观和自然的,它模仿了人类工作的模式:一次只做一件事情。起床,洗漱,下楼开始早餐。如同在程序设计语言中,每一个真实世界中的活动都是对一个finer-grained actions 序列的抽象:打开壁橱,选择一种茶,倒一些茶叶进壶,看看茶壶中是否有足够的水,如果没有就加入一些,将其放在火炉上,等待水开……最后一个步骤等待水开的事件意味着一定程度的异步。在水加热的这段时间里,你可以选择干等,还可以选择做寿司或者看一份报纸(另一个异步事件),同时留意着茶壶。茶壶和寿司烘烤器的制作商们知道他们的产品通常被异步地使用,因此茶壶和寿司烘烤器在它们的任务完成时会发出一种声音信号。在顺序和异步中寻找平衡是高效人士的特点,也是并发程序的关键。

The same concerns (resource utilization, fairness, and convenience) that motivated the development of processes also motivated the development of threads. Threads allow multiple streams of program control flow to coexist within a process. They share process-wide resources such as memory and file handles, but each thread has its own program counter, stack, and local variables. Threads also provide a natural decomposition for exploiting hardware parallelism on multiprocessor systems; multiple threads within the same program can be scheduled simultaneously on multiple CPUs.

资源利用,公平,便利推动了处理器的发展,也激励了线程的发展。线程能让多个程序控制流共存于一个处理器中。它们共享内存,文件句柄等处理机资源,但是每个线程拥有它自己的程序计数器,堆栈和局部变量。线程也提供了一个在多处理器中为开发硬件并行的自然分解:单个程序中的多线程能同时被安排在多个不同的CPU中执行。

Threads are sometimes called lightweight processes, and most modern operating systems treat threads, not processes, as the basic units of scheduling. In the absence of explicit coordination, threads execute simultaneously and asynchronously with respect to one another. Since threads share the memory address space of their owning process, all threads within a process have access to the same variables and allocate objects from the same heap, which allows finer-grained data sharing than inter-process mechanisms. But without explicit synchronization to coordinate access to shared data, a thread may modify variables that another thread is in the middle of using, with unpredictable results.

       线程通常称为轻量级进程,大多数现代操作系统都将线程而非进程作为调度的基本单位。由于缺乏详尽的协作,线程与其他线程同步和异步地执行。因为线程共享所属的进程地址空间,所有同属于一个进程的线程能存取同一的变量和从同一个堆中分配的对象,这能够比进程间通信机制更好地共享精粒度数据。然而如果没有同步机制来协调处理共享数据,那么一个线程可能会更改另一个线程正在使用中的数据,带来不可预料的后果。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值