并发性防御式编程_第1页
并发性防御式编程_第2页
并发性防御式编程_第3页
并发性防御式编程_第4页
并发性防御式编程_第5页
已阅读5页,还剩20页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1/1并发性防御式编程第一部分并发安全的编程原则和方法 2第二部分线程安全数据结构的设计 4第三部分无锁并发数据访问机制 7第四部分死锁检测与避免策略 9第五部分并发异常处理的指南和实践 12第六部分内存可见性和原子性保证 15第七部分高性能并发应用程序的优化 17第八部分并发性测试和性能分析 19

第一部分并发安全的编程原则和方法并发安全的编程原则和方法

并发安全的原则

*互斥访问共享数据:确保同一时间只有一个线程可以访问共享数据,从而避免数据竞争。

*避免死锁:确保线程不会永久等待其他线程释放锁或资源。

*有序性保证:遵循特定顺序访问共享数据,以避免数据损坏或不一致。

*内存可见性:确保对共享数据的修改对其他线程可见,防止读取到过时的值。

并发安全的编程方法

*互斥锁(Mutex):允许一次只有一个线程获得锁,确保对共享数据具有互斥访问。

*自旋锁(Spinlock):忙等锁,当锁被占用时,线程不会进入阻塞状态,而是不断循环,直到锁可用。

*读写锁(ReadWriteLock):允许多个线程同时读取共享数据,但只允许一个线程同时写入。

原子操作

*原子变量:保证对变量的读写操作是原子性的,不会被中断。

*CAS(比较并交换):原子地比较并修改一个变量的值,从而避免多个线程同时修改同一变量。

无锁技术

*CAS和Fetch-and-Add:利用原子操作实现无锁操作。

*无锁数据结构:设计无需锁即可操作的并发数据结构。

*Copy-on-write:创建共享对象的副本,线程在对副本进行修改后才将其写入共享内存。

内存屏障

*编译器屏障:强制编译器执行特定内存顺序,确保对共享数据的修改对其他线程可见。

*硬件屏障:强制处理器执行特定内存顺序,防止处理器对内存进行重新排序。

其他方法

*线程局部存储(TLS):为每个线程提供私有存储,避免共享数据竞争。

*消息传递:通过消息队列或管道进行线程间通信,减少共享数据竞争。

*程序设计模式:采用特定模式,如生产者-消费者模式或观察者模式,保持并发性。

实践建议

*仔细标识需要并发访问的共享数据。

*选择合适的并发控制机制,根据性能和安全性考虑因素。

*避免不必要的同步,因为过度同步会降低性能。

*考虑可扩展性和健壮性,确保应用程序在并发环境中稳定运行。

*进行严格测试,以验证并发安全性和查找潜在问题。第二部分线程安全数据结构的设计关键词关键要点【线程安全数据结构的设计】,

1.原子性操作:

-保证对变量的读写操作是原子性的,避免多个线程同时访问导致数据不一致。

-例如,使用锁或CAS(比较并交换)操作保证变量的原子性。

2.可见性保障:

-确保线程对共享变量的修改可以被其他线程及时感知。

-例如,使用volatile关键字或栅栏指令来保证内存可见性。

3.有序性维护:

-确保线程对共享变量的修改顺序与程序代码的执行顺序一致。

-例如,使用happens-before规则或memorybarriers来维护有序性。

【使用锁进行同步】,线程安全数据结构的设计

并发和线程安全性

并发是指多个线程同时访问共享内存的现象。线程安全性是指数据结构在并发环境中可以正确访问,不会出现数据竞争或其他问题。

数据竞争

数据竞争是指多个线程同时访问和修改共享数据,导致数据不一致或损坏。

设计线程安全数据结构的策略

设计线程安全数据结构有以下几种策略:

互斥锁

互斥锁通过限制一次只有一个线程可以访问共享数据来确保线程安全性。然而,互斥锁可能会导致死锁或锁争用。

原子操作

原子操作是不可中断的操作,可以保证数据修改的完整性。然而,原子操作通常效率较低。

无锁数据结构

无锁数据结构使用特殊算法来实现线程安全性,而无需使用互斥锁或原子操作。无锁数据结构通常比有锁数据结构效率更高。

常见线程安全数据结构

线程安全队列

线程安全队列使用互斥锁或原子操作来保护插入和删除操作。例如:

*`std::queue`(C++STL)

*`ConcurrentLinkedQueue`(Java)

线程安全栈

线程安全栈使用原子操作或无锁算法来保护压入和弹出操作。例如:

*`std::stack`(C++STL)

*`ConcurrentSkipListMap`(Java)

线程安全哈希表

线程安全哈希表使用分段锁或无锁算法来保护键值对。例如:

*`std::unordered_map`(C++STL)

*`ConcurrentHashMap`(Java)

线程安全树

线程安全树使用互斥锁或无锁算法来保护节点插入、删除和查找。例如:

*`std::map`(C++STL)

*`ConcurrentSkipListSet`(Java)

无锁数据结构的优势

*效率高:无锁数据结构通常比有锁数据结构效率更高,因为它们避免了锁争用。

*可伸缩性强:无锁数据结构通常更具可伸缩性,因为它们不会导致死锁。

*无死锁风险:无锁数据结构通过消除对互斥锁的使用来消除死锁风险。

无锁数据结构的缺点

*实现复杂:无锁数据结构的实现通常比有锁数据结构更复杂。

*潜在的开销:无锁数据结构可能涉及额外的开销,例如使用较复杂的算法或额外的内存使用。

选择线程安全数据结构

选择线程安全数据结构时,需要考虑以下因素:

*并发级别:并发访问数据结构的线程数量。

*操作类型:插入、删除、查找或其他操作。

*性能要求:所需的数据结构效率。

*可伸缩性要求:数据结构的可伸缩性对于处理高并发量。

通过考虑这些因素,可以选择最适合特定应用程序需求的线程安全数据结构。第三部分无锁并发数据访问机制关键词关键要点原子操作

1.原子操作是不可中断的单一操作,确保数据一致性和完整性。

2.硬件级原子操作,例如compare-and-swap(CAS)和fetch-and-add,在底层提供互斥锁,无锁无等待。

3.软件级原子操作,例如atomic_add()和atomic_exchange(),使用处理器提供的lock-prefix指令。

非阻塞算法

1.非阻塞算法通过连续重试来处理锁冲突,避免线程阻塞。

2.常见非阻塞算法有乐观并发的多版本并发控制(MVCC),使用快照隔离保证数据一致性。

3.乐观并发的无锁队列和无锁集合,实现无锁的插入、删除和查找操作。

无锁数据结构

1.无锁数据结构使用原子操作和非阻塞算法,实现无锁并发访问。

2.常用无锁数据结构有无锁队列、无锁栈、无锁链表和无锁哈希表。

3.无锁数据结构通过无锁算法确保操作的可视性、有序性和原子性,提升并发性能。

并发内存回收

1.并发内存回收通过非阻塞算法,在多线程环境下安全回收内存。

2.分代收集器和增量收集器等并发回收器,允许垃圾收集器与应用程序并发运行。

3.并发内存回收减少应用暂停时间,提高并发性。

无锁同步原语

1.无锁同步原语,如自旋锁和CAS操作,提供无阻碍的线程同步。

2.自旋锁避免线程阻塞,通过忙循环反复检查锁状态。

3.CAS操作使用原子指令更新共享变量,实现无锁互斥。

内存栅栏

1.内存栅栏是一种CPU指令,用于强制处理器按特定顺序执行内存操作。

2.内存栅栏防止指令重排,确保原子操作的正确执行。

3.不同类型的内存栅栏有store-load栅栏、load-store栅栏和full栅栏,用于不同场景的同步和可见性保证。无锁并发数据访问机制

无锁并发数据访问机制是一类并发编程技术,它允许多个线程同时访问共享数据结构,而无需使用锁或其他同步机制。这可以通过使用原子操作或非阻塞算法来实现。

原子操作

原子操作是一种操作,它要么完全执行,要么根本不执行。这意味着其他线程不能打断原子操作的执行过程。例如,在C++中,使用`std::atomic`库可以执行原子操作。

非阻塞算法

非阻塞算法是算法的一种,它在执行过程中不会产生死锁或饥饿。非阻塞算法通常使用循环,直到操作成功或达到超时条件为止。例如,无锁队列是一种非阻塞算法,它使用循环来插入或删除元素,直到操作成功或队列已满。

无锁并发数据访问机制的优点

*可扩展性:无锁机制允许多个线程同时访问数据结构,从而提高可扩展性。

*性能:无锁机制避免了锁争用,从而提高性能。

*容错性:无锁机制避免了死锁和饥饿,从而提高容错性。

无锁并发数据访问机制的缺点

*复杂性:无锁机制的实现通常比使用锁的机制更复杂。

*适用性:无锁机制并不适用于所有场景。例如,当需要对数据结构进行长时间的修改时,使用锁可能更合适。

常见的无锁并发数据访问机制

*原子计数器:一个只能通过原子操作进行增减或比较的计数器。

*无锁队列:一个允许多个线程同时插入或删除元素的队列。

*无锁链表:一个允许多个线程同时插入或删除节点的链表。

*读写锁:一种允许多个线程同时进行读取操作,但仅允许一个线程进行写入操作的锁。

使用无锁并发数据访问机制的注意事项

*内存屏障:使用无锁机制时,需要使用内存屏障来确保不同线程之间数据的可见性和一致性。

*调试:调试无锁代码可能具有挑战性,因为需要考虑数据竞争和非确定性执行。

*性能:无锁机制并不总是比有锁机制更快。在选择无锁机制时,应考虑具体场景和性能要求。第四部分死锁检测与避免策略关键词关键要点死锁检测

1.死锁检测机制通过定期探测系统状态来识别死锁情况。

2.常见死锁检测算法包括Banker算法和哈斯特根算法,它们分别采用资源分配图和矩阵表示系统资源分配情况。

3.死锁检测算法的挑战在于如何高效地发现死锁,避免虚假检测和检测延迟。

死锁避免

1.死锁避免策略通过在资源分配前检查系统状态,确保不会发生死锁。

2.常见死锁避免策略包括无退避算法和银行家算法变体,它们限制进程对资源的请求,以防止出现循环等待。

3.死锁避免策略需要准确预测进程的行为和资源需求,并在不过度限制进程的情况下实现死锁预防。死锁检测与避免策略

#死锁检测

死锁检测是一种动态技术,它在系统运行时检查是否存在死锁。当检测到死锁时,系统会采取某种措施,例如终止死锁中的进程或回滚它们的分配。

死锁检测算法:

*资源分配图法:构建一个系统资源分配图,如果图中存在循环,则说明存在死锁。

*等待-为图法:构建一个等待-为图,如果图中存在环,则说明存在死锁。

*Haskell-Coffman条件:检查以下四个条件是否同时满足:

*互斥条件:进程独占使用资源。

*持有并等待条件:进程持有资源,同时等待其他资源。

*不可抢占条件:进程不能被强制剥夺资源。

*循环等待条件:存在一组进程,每个进程都在等待前一个进程持有的资源。

#死锁避免策略

死锁避免策略是一种静态技术,它在资源分配之前检查是否存在死锁的可能性。如果检测到死锁,系统会拒绝分配资源,从而避免死锁发生。

死锁避免算法:

*安全性算法:根据当前的资源分配和进程请求,判断系统是否处于安全状态。如果存在一个安全的序列,则不会发生死锁。

*银行家算法:一种安全性算法,它使用资源分配图来模拟系统行为并检测死锁。

*资源有序分配策略:将资源按某种顺序分配给进程,从而避免死锁的发生。

*死锁预防策略:通过限制进程对资源的访问,防止死锁发生。例如,不允许进程同时持有超过一种类型的资源。

#死锁检测与避免策略的比较

检测策略:

*优点:当死锁发生时,能够及时检测并采取措施。

*缺点:开销较高,可能会影响系统的性能。

避免策略:

*优点:可以有效防止死锁发生。

*缺点:可能会限制系统的资源利用率。

#选择死锁控制策略

选择合适的死锁控制策略取决于系统的特点和要求。一般来说:

*如果系统对性能要求很高,可以选择检测策略,因为它不会限制资源利用率。

*如果系统对安全性要求很高,可以选择避免策略,因为它可以有效防止死锁。

*大多数实际系统采用混合策略,即在运行时进行检测,并在分配关键资源时进行避免。

#实践中的考虑因素

*死锁的影响:死锁可能会导致系统崩溃或性能严重下降。了解死锁的潜在影响对于选择合适的控制策略至关重要。

*资源类型:不同的资源类型可能需要不同的死锁控制策略。例如,使用共享内存的进程可能需要更严格的策略。

*进程交互:进程之间的交互模式可能会影响死锁出现的概率。例如,高度竞争性的进程更容易出现死锁。

*系统监控:对于检测死锁的系统,定期监视死锁的发生情况至关重要。这有助于调整策略,以提高系统的鲁棒性。第五部分并发异常处理的指南和实践关键词关键要点并发异常处理的指南和实践

主题:错误处理策略

*了解不同错误处理策略(例如,终止、重试、降级等)的优点和缺点。

*权衡每个策略的性能影响、恢复时间目标和用户体验。

*根据应用程序的具体需求选择最佳策略。

主题:异常边界

并发异常处理的指南和实践

在并发编程中,异常处理是一个至关重要的方面,因为它可以确保应用程序在遇到意外事件时保持健壮性和可恢复性。以下是并发异常处理的全面指南:

1.非阻塞异常处理

在并发环境中,异常通常是通过非阻塞机制处理的。这意味着异常不会立即中断线程执行,而是被捕获并存储在特定的位置。这允许应用程序继续执行,直到到达安全点,届时可以对异常进行处理。

2.异常传播和处理

在并发环境中,异常可以通过以下方式传播:

*本地传播:异常在当前线程内传播。

*线程间传播:异常通过线程间通信机制传播到其他线程。

异常处理可以通过以下方式进行:

*本地处理:异常在本地捕获和处理。

*协作处理:异常在多个线程或进程之间协作处理。

3.安全点

安全点是在并发应用程序中定义的特定位置,可以在这些位置对异常进行安全处理。常见的安全点包括:

*锁边界:当线程进入或退出临界区时。

*阻塞点:当线程等待资源或输入时。

*线程终止:当线程结束执行时。

4.异常处理策略

对于并发异常处理,有几种不同的策略可供选择:

*抛出异常:将异常抛出到调用线程,以便在安全点进行处理。

*捕获并重新抛出:捕获异常并在特定的安全点重新抛出。

*捕获并忽略:捕获异常但不采取任何进一步的行动。

*捕获并恢复:捕获异常并尝试恢复应用程序状态。

5.异常处理最佳实践

处理并发异常时,遵循以下最佳实践至关重要:

*使用非阻塞异常处理:避免使用阻塞异常处理,以防止死锁和性能问题。

*定义明确的安全点:仔细定义安全点以确保异常可以安全处理。

*使用适当的异常处理策略:根据具体情况选择最佳的异常处理策略。

*进行全面的测试:彻底测试应用程序以确保其能够正确处理异常。

*使用异常处理框架:考虑使用异常处理框架,例如Java的`try-with-resources`或C#的`using`语句,以简化异常处理。

6.常见并发异常

在并发编程中,一些常见异常包括:

*死锁:当两个或多个线程无限期地等待彼此释放锁时。

*竞态条件:当多个线程并行执行同一部分代码并导致不确定结果时。

*原子性违规:当多个线程同时访问和修改共享数据时。

*内存一致性错误:当多个线程在不同的缓存中访问同一数据时。

*线程终止异常:当线程在意外情况下终止时。

7.异常处理工具和技术

以下工具和技术可帮助管理并发异常:

*异常处理语言特性:如Java中的`try-catch`和C#中的`try-using`。

*异常处理框架:如Java的`try-with-resources`和C#的`using`语句。

*线程池:用于管理线程执行并处理异常。

*锁和同步原语:用于协调线程访问共享资源。

*测试框架:用于测试并发应用程序中的异常处理。

结论

并发异常处理是一个至关重要的方面,可以确保并发应用程序的健壮性和可恢复性。通过遵循本指南中的原则和实践,开发人员可以设计和实现能够有效处理异常的可靠并发应用程序。第六部分内存可见性和原子性保证关键词关键要点【内存屏障】:

*

*限制内存重排,确保指令执行顺序与程序意图保持一致。

*不同类型内存屏障适用于不同场景,包括顺序屏障、负荷屏障和存储屏障。

*正确使用内存屏障可以避免数据竞争和内存可见性问题。

【原子性】:

*内存可见性和原子性保证

在并发编程中,内存可见性是指确保一个线程所做的写入对其他线程可见。原子性保证是指确保一个操作作为一个整体被执行,不会被其他线程中断。

内存可见性

在多线程环境中,每个线程都有自己的本地缓存,用于存储从主内存中获取的数据。当一个线程对数据进行写入时,它只会写入自己的本地缓存。其他线程看不到此写入,直到它们从主内存中重新加载数据。

这可能导致以下问题:

*可见性窗口:这是本地缓存与主内存不同步的时间段。在此期间,其他线程看不到对数据的写入,这可能会导致数据不一致。

*指令重排序:编译器和CPU可能会重新排序指令,这可能会导致一个线程看到对数据的写入,而另一个线程看不到。

为了解决这些问题,Java语言提供了volatile和synchronized关键字。

*volatile:将一个变量声明为volatile会强制每次加载变量值时都从主内存中获取。它还可以防止指令重排序。

*synchronized:将一个方法或代码块声明为synchronized会获取一个监视器锁,该锁阻止其他线程同时执行该方法或代码块。

原子性保证

原子性保证是指确保一个操作作为一个整体被执行,不会被其他线程中断。在Java中,原子操作是通过以下方式实现的:

*Atomic变量:这些变量是线程安全的,并提供原子读写操作。

*锁:锁是一种同步机制,当一个线程获取锁时,它可以独占访问临界区,直到释放锁为止。

*CAS(比较并交换):CAS是一条原子指令,用于条件性地更新变量。它将当前值与预期的值进行比较,如果相等,则进行更新。

原子性保证对于防止以下问题至关重要:

*竞争条件:当多个线程试图同时访问共享数据时,可能会发生竞争条件。这可能导致数据不一致或死锁。

*数据竞赛:数据竞赛是指两个或多个线程同时访问共享数据,并且至少一个线程对数据进行写入。这可能导致数据损坏。

通过使用适当的同步技术,可以实现内存可见性和原子性保证,确保并发程序的正确性和一致性。第七部分高性能并发应用程序的优化高性能并发应用程序的优化

在并发编程中,性能优化至关重要,特别是对于处理大量并发请求或处理时间敏感任务的应用程序。以下是一些优化高性能并发应用程序的策略:

1.优化锁存机制

*细粒度锁存:使用粒度更细的锁来减少锁争用,仅锁定数据或资源的必需部分。

*无锁数据结构:考虑使用无锁数据结构,例如原子操作和非阻塞数据结构,以避免锁争用。

*锁消除技术:探索锁消除技术,例如读-复制更新和乐观并发控制,以在某些情况下避免锁的开销。

2.减少线程切换

*池化线程:创建线程池并重用线程,以减少线程创建和销毁的开销。

*优化线程调度:使用高效的线程调度算法,例如工作窃取,以平衡线程负载并提高吞吐量。

*避免不必要的同步:仔细考虑同步需求,避免对频繁访问的数据或资源进行过度同步。

3.利用并行性和异步处理

*多核编程:利用多核处理器,创建多个线程或使用并行编程模型,例如OpenMP或CUDA,以充分利用可用资源。

*异步I/O:使用异步I/O操作,例如非阻塞套接字或事件驱动编程,以避免I/O操作阻塞线程。

*任务并行化:将大型任务分解为更小的任务,并行执行这些任务,以提高总体吞吐量。

4.优化内存使用和数据布局

*减少内存争用:使用专用数据结构和隔离技术来减少内存争用,例如padding和对齐。

*优化缓存利用率:注意数据布局以最大化缓存利用率,例如使用局部性友好的数据结构和访问模式。

*减少内存分配:尽可能重用内存并尽量减少内存分配,以提高性能并降低内存碎片。

5.性能分析和调试

*性能分析工具:使用性能分析工具,例如perf或gprof,来识别性能瓶颈并指导优化工作。

*调试工具:使用调试工具,例如gdb或valgrind,来隔离竞争条件、死锁和其他并发问题。

*持续监控:持续监控应用程序的性能指标,例如吞吐量、延迟和资源利用率,以主动识别和解决性能问题。

通过采用这些优化策略,开发人员可以显著提高并发应用程序的性能,满足高吞吐量、低延迟和可扩展性方面的要求。第八部分并发性测试和性能分析关键词关键要点【并发性测试】

1.压力测试:模拟高并发的真实场景,评估系统在极限情况下的性能和稳定性。

2.负载测试:逐渐增加并发用户数,观察系统响应时间、吞吐量和资源消耗情况。

3.耐久性测试:长时间运行并发场景,检测系统在长时间高负荷下的稳定性和抗故障能力。

【性能分析】

并发性测试和性能分析

并发性测试

并发性测试旨在评估系统在高并发访问情况下的表现,重点关注以下方面:

*吞吐量:系统在特定时间内处理请求的速度。

*延迟:从请求发出到收到响应所需的时间。

*响应时间:系统完成特定任务所需的时间,从请求发出到任务完成。

*可扩展性:系统随着并发负载增加而保持性能的能力。

常见的并发性测试方法包括:

*负载测试:模拟大量用户同时访问系统,评估系统在不同负载下的性能。

*压力测试:将并发负载推至系统极限,以确定其在极端条件下的行为。

*浸泡测试:在长时间内以持续的高并发负载对系统进行测试,以发现潜在的性能问题。

性能分析

性能分析涉及识别和分析系统性能瓶颈,以提高其效率和响应能力。以下是一些常见的性能分析技术:

*剖析:收集应用程序代码执行时间和内存使用情况的数据,以识别耗时的操作。

*追踪:跟踪应用程序请求的路径,以发现延迟或阻塞的来源。

*基准测试:将系统与类似配置的基准系统进行比较,以评估其性能。

性能分析工具可以帮助执行以下任务:

*收集性能指标:收集有关CPU使用率、内存使用情况、网络活动和其他性能相关指标的数据。

*识别瓶颈:分析收集的数据,以识别影响系统性能的瓶颈。

*诊断问题:提供有关性能问题根本原因的详细信息,以便采取纠正措施。

并发性防御式编程

在多线程环境中编写代码时,采用防御式编程实践至关重要,以处理并发引起的潜在问题。以下是一些最佳实践:

*同步机制:使用锁、互斥器或信号量等同步机制来防止多个线程同时访问共享资源。

*原子操作:使用原子操作,例如原子计数器或原子更新,以确保并发操作的正确性。

*线程安全集合:使用线程安全集合,例如ConcurrentHashMap或CopyOnWriteArrayList,以防止并发操作导致数据损坏。

*避免竞争条件:仔细考虑代码中可能导致竞争条件的区域,并实施适当的预防措施。

*测试和验证:通过并发性测试和性能分析,确保代码在并发环境中运行正确且高效。

结论

并发性测试和性能分析对于确保并发系统的高性能和可扩展性至关重要。通过采用防御式编程实践,开发人员可以构建能够在高并发负载下可靠运行的健壮系统。关键词关键要点主题名称:线程安全的数据结构

关键要点:

1.使用原子类型和无锁数据结构,如AtomicInteger和ConcurrentHashMap,确保变量或集合的访问和修改是原子性的。

2.对于需要更复杂数据结构的情况,可以使用同步容器,如synchronizedMap和synchronizedList,通过内嵌锁机制确保访问和修改操作的有序性。

3.避免使用不可变数据结构,如String或Integer,因为这些数据结构不可变,可能存在并发的修改操作导致数据不一致。

主题名称:线程同步

关键要点:

1.使用synchronized关键字或ReentrantLock等锁机制来控制对共享资源的访问,防止并发访问导致数据不一致。

2.使用lock-free算法,如CAS(compare-and-swap)和LL/SC(load-linked/store-conditional),实现无锁线程同步,提高性能和可扩展性。

3.避免使用wait()和notify()等阻塞式同步机制,因为它们可能会导致线程饥饿或死锁。

主题名称:死锁预防与检测

关键要点:

1.设计系统时,避免创建循环等待的情况,即一个线程等待另一个线程释放资源,而另一个线程又等待前一个线程释放资源。

2.使用死锁检测算法,如wait-forgraph算法,定期检查系统中是否存在死锁,并采取相应措施加以处理。

3.使用超时机制,当线程等待某个资源超过指定时间时,强制释放该资源并终止等待。

主题名称:内存可见性

关键要点:

1.了解Java的内存模型,以及它如何影响多线程程序中变量的可见性。

2.使用volatile关键字修饰共享变量,以确保对它的所有修改都能立即对其他线程可见。

3.使用CAS和LL/SC等操作

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论