




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
17/22并发数组的线程安全初始化第一部分并发数组的线程安全概念 2第二部分线程安全初始化的必要性 4第三部分JSR-166ejava.util.concurrent包中的并发数组 5第四部分锁机制在并发数组中的应用 7第五部分原子操作的应用与优势 10第六部分延迟初始化的线程安全性 13第七部分容器的线程安全初始化实践 15第八部分并发数组线程安全初始化的最佳实践 17
第一部分并发数组的线程安全概念并发数组的线程安全概念
线程安全并发数组是一种数据结构,它允许多个线程同时访问和修改数组元素,同时保持数据一致性和完整性。线程安全数组通过内置的同步机制实现,该机制负责协调对数组的并发访问,防止数据损坏和racecondition。
racecondition
racecondition发生在一个或多个线程访问共享资源(如并发数组)时,并且执行的顺序对结果产生影响。在没有同步的情况下,线程对共享资源的访问顺序是不可预测的,这会导致数据损坏或不一致性。
同步机制
为了防止racecondition,并发数组使用各种同步机制来控制对数组元素的访问。这些机制包括:
*锁:锁是一种同步原语,它允许一次仅一个线程访问临界区(例如并发数组的元素)。其他线程在获取锁之前必须等待,从而确保数据的原子性修改。
*原子操作:原子操作是一种特殊类型的指令,它确保对内存位置的操作是原子的,这意味着它不能被其他线程中断。并发数组使用原子操作来进行读/写操作,以保持数据的完整性。
*无锁技术:无锁技术使用乐观的并发控制策略,允许多个线程同时访问共享资源,而无需显式锁定。这些技术依赖于争用检测和重试机制,以确保数据的正确性。
线程安全数组的优点
*并发性:并发数组允许多个线程同时访问和修改数组元素,提高了应用程序的性能和可扩展性。
*数据完整性:内置的同步机制确保了数据的原子性和一致性,防止了racecondition和数据损坏。
*易用性:并发数组提供了与常规数组类似的简单和熟悉的接口,降低了开发线程安全应用程序的复杂性。
线程安全数组的实现
并发数组通常作为标准库或第三方库的一部分实现。这些实现提供了各种线程安全数据结构,包括:
*线程安全向量:一种动态大小的数组,支持元素的添加、删除和访问。
*线程安全哈希表:一种高效的数据结构,用于在键值对之间进行快速查找和插入。
*线程安全队列:一种先进先出的数据结构,支持元素的入队和出队操作。
使用线程安全数组的最佳实践
为了最大限度地发挥并发数组的优点,建议遵循以下最佳实践:
*始终使用正确的同步机制,以匹配具体的并发需求和性能要求。
*尽可能避免过度的同步,因为它会降低应用程序的性能。
*仔细考虑数组元素的数据类型,并使用适当的同步机制来确保其正确性。
*定期进行并发性测试,以确保应用程序在多线程环境中正常工作。第二部分线程安全初始化的必要性线程安全并发的必要性
在多线程环境中操作数据结构时,线程安全至关重要。没有线程安全,并行的线程之间可能发生竞争条件和数据争用,从而导致不可预知的поведение和数据损坏。
竞争条件
竞争条件是指多个线程同时读取或写入共享数据时,根据执行的顺序,它们的行为可能不同。一个线程可以修改数据,而另一个线程同时读取该数据,从而导致不一致的结果。
数据争用
当多个线程同时尝试修改共享数据时,就会发生数据争用。这会导致两个或更多线程互相覆盖它们的更改,从而导致数据损坏。
线程安全并发
要确保并发环境中的数据安全,数据结构需要具有线程安全性。线程安全要求如下:
*原子性:每个操作必须是原子性的,这意味着它不可被其他线程中断。
*一致性:操作必须保持数据一致性,这意味着它不会导致数据损坏或丢失。
*隔离性:每个线程必须与其他线程隔离,这意味着它只能看到自己的本地副本数据。
线程安全并发的实现
实现线程安全并发有几种方法,包括:
*同步化原语:如锁、互斥量和读写锁,这些原语可用于控制对共享数据的并发アクセス。
*不可变数据结构:通过使用不可变数据结构,例如元组和不可变列表,可以消除对同步原语的需要。
*并发容器:一些编程库提供线程安全的并发容器,如并发列表和并发队列。第三部分JSR-166ejava.util.concurrent包中的并发数组关键词关键要点【java.util.concurrent包中的并发数组】:
1.ConcurrentArrayList:线程安全ArrayList,采用了分段锁技术,避免了ArrayList的锁竞争问题。
2.ConcurrentHashMap:线程安全的HashMap,采用了分段锁技术和哈希算法,大大提高了并发性能。
3.ConcurrentLinkedDeque:线程安全的双向队列,采用无锁队列算法,具有高并发性。
【ConcurrentSkipListMap】:
并发数组的线程安全初始化
JSR-166ejava.util.concurrent包中的并发数组
java.util.concurrent包包含几种线程安全的并发数组类,它们提供了对共享数组的并发访问。这些类包括:
*ConcurrentHashMap:一个线程安全的散列表,可以同时从多个线程写入和读取。
*ConcurrentSkipListMap:一个线程安全的并发跳表,具有比红黑树更好的并发性。
*ConcurrentLinkedQueue:一个线程安全的并发队列,可以同时从多个线程写入和读取。
*ConcurrentLinkedDequeue:一个线程安全的并发双端队列,可以同时从多个线程写入和读取。
*ConcurrentHashMap.KeySetView:一个线程安全的并发集合视图,它表示ConcurrentHashMap的键集。
*ConcurrentHashMap.ValuesView:一个线程安全的并发集合视图,它表示ConcurrentHashMap的值集。
*ConcurrentHashMap.EntrySetView:一个线程安全的并发集合视图,它表示ConcurrentHashMap的条目集。
线程安全初始化
为了确保并发数组的线程安全,在初始化时必须采取一些预防措施:
*避免使用非线程安全的类:不要使用非线程安全的集合或其他类来初始化并发数组。这可能导致数据损坏或并发问题。
*使用并发构造函数:大多数并发数组类都提供并发构造函数,这些构造函数可以安全地从多个线程初始化数组。例如,ConcurrentHashMap可以使用以下并发构造函数进行初始化:
```java
ConcurrentHashMap<String,Integer>map=newConcurrentHashMap<>();
```
*使用同步机制:如果必须使用非并发类来初始化并发数组,则必须使用同步机制来保护初始化过程。例如:
```java
map=newHashMap<>();
}
```
最佳实践
以下是一些关于并发数组线程安全初始化的最佳实践:
*始终使用并发类的并发构造函数进行初始化。
*避免使用非线程安全的类进行初始化。
*如果必须使用非线程安全的类,请使用同步机制保护初始化过程。
*在初始化后,不要将并发数组的引用传递给非线程安全的类。
通过遵循这些最佳实践,您可以确保并发数组的线程安全初始化,并防止数据损坏和并发问题。第四部分锁机制在并发数组中的应用关键词关键要点并发数组的同步机制
1.原子操作:对共享内存的访问必须是原子的,即不可中断,这确保了数据的完整性和一致性。
2.互斥锁:是一种同步机制,它允许同一时间只有一个线程访问共享数据,确保了并发操作的互斥性。
3.读写锁:是一种更细粒度的同步机制,它允许多个线程同时读数据,但只允许一个线程写数据,提高了并发效率。
锁粒度
1.粗粒度锁:一次锁定整个数组,提供最强的同步,但也会导致并发度降低。
2.细粒度锁:只锁定数组的特定部分,允许更高并发度,但需要更复杂的设计和实现。
3.无锁算法:利用特殊算法避免使用显式锁,提供了最高的并发度,但实现难度通常较高。
锁性能
1.锁争用:多个线程同时获取同一把锁,可能导致性能瓶颈和死锁。
2.锁开销:获得和释放锁的操作需要耗费时间,影响整体性能。
3.可扩展性:锁机制应能适应不同规模的并发操作,避免成为系统瓶颈。
锁选择
1.并发程度:并发线程数量影响锁的选择,高并发度需要更细粒度的锁。
2.数据访问模式:读写操作的比例和访问频率影响锁的选择,读密集型操作可使用读写锁。
3.性能需求:系统对性能和可扩展性的要求影响锁的选择,无锁算法可提供最高性能。
前沿趋势
1.自旋锁:一种非阻塞锁,在获取锁失败时忙等,减少了锁争用的开销。
2.乐观并发控制:假设并行操作不会产生冲突,并使用版本控制和冲突检测进行修复,提供了更高的并发度。
3.无锁数据结构:利用特定算法和数据结构设计,避免使用显式锁,提供最优的并发效率。锁机制在并发数组中的应用
在并发环境中,当多个线程同时访问共享数据(如数组)时,可能会导致数据不一致和竞争条件。为了确保数组在并发访问下的数据完整性和线程安全性,需要采用适当的同步机制,其中一种常用方法就是锁机制。
锁的原理
锁是一种同步原语,它通过控制对共享资源的访问来实现线程同步。当一个线程需要访问受保护的资源时,它必须先获取该资源的锁。如果锁已被其他线程持有,该线程将被阻塞,直到锁释放。这样,可以确保任何时刻只有一个线程访问受保护的资源,避免了数据竞争。
并发数组中的锁机制
在并发数组中,锁主要用于保护数组元素的读写操作。每个数组元素都与一个相关的锁关联,当一个线程需要访问该元素时,它必须首先获取与该元素关联的锁。只有当该线程成功获取锁后,它才能对该元素进行读写操作。
锁的实现
锁的实现方式有多种,以下列出其中一些常见的实现:
*互斥锁(Mutex):互斥锁是最基本的锁实现,它一次只允许一个线程持有锁。
*自旋锁(Spinlock):自旋锁是一种比互斥锁更轻量级的锁,它允许多个线程在等待锁时自旋(不断轮询锁的状态)。
*读写锁(RWLock):读写锁允许多个线程同时获取锁进行读操作,但只有一个线程可以同时获取锁进行写操作。
*原子操作:原子操作是一种特殊的指令,它可以确保对内存中单个位置的读写操作作为一个不可分割的整体执行,从而避免了并发访问下的数据竞争。
锁的粒度
锁的粒度是指锁所保护的数据范围。选择合适的锁粒度非常重要,粒度太粗可能会导致不必要的阻塞,而粒度太细又会产生过多的开销。
在并发数组中,锁的粒度通常与数组的结构有关。例如:
*元素级锁:每个数组元素都与一个单独的锁关联,提供最细粒度的保护。
*分段锁:数组被划分为多个段,每个段都有一个单独的锁。
*数组级锁:整个数组由一个单一的锁保护,提供最粗粒度的保护。
锁的性能影响
使用锁机制会带来一定的性能开销,主要表现在:
*阻塞:当一个线程无法获取锁时,它会被阻塞,从而可能延长程序的执行时间。
*争用:当多个线程同时争夺同一把锁时,可能会产生锁争用,导致应用程序性能下降。
*死锁:当两个或多个线程相互等待对方释放锁时,可能会发生死锁,导致应用程序崩溃。
因此,在使用锁机制时,需要仔细权衡性能开销和同步需求。第五部分原子操作的应用与优势原子操作的应用与优势
理解原子操作
原子操作是一组不可中断的指令序列,这些指令作为一个整体执行或完全不执行。这意味着在执行原子操作时,不会被其他线程或处理器中断。这种不可中断的执行对于实现线程安全至关重要。
应用场景
原子操作在多线程编程中广泛应用于以下场景:
*并发数据结构:确保并发数据结构(如链表、队列、栈等)的原子更新。
*共享资源管理:控制对共享资源(如文件、数据库记录等)的并发访问。
*计数器和标志:原子地更新和检查计数器或标志变量。
*锁机制:实现轻量级锁或互斥量,协调对共享数据的访问。
*内存屏障:控制对共享内存的访问顺序,确保指令按预期顺序执行。
优势
原子操作提供了以下优势:
线程安全:由于原子操作不可中断,它们可以确保在多线程环境中对共享数据的安全更新,从而消除竞争条件和数据损坏问题。
高性能:与其他线程安全机制(如互斥量)相比,原子操作的开销更低,因为它们不需要获取和释放锁。在某些情况下,原子操作甚至可以提供比非线程安全操作更高的性能。
可伸缩性:原子操作可以在广泛的硬件平台和操作系统上使用,使其成为实现跨平台线程安全的可靠解决方案。
易于实现:许多编程语言和库都提供了内置的原子操作,这使得实现线程安全代码变得更加容易和便捷。
具体实现
常见的原子操作实现包括:
*比较并交换(CAS):原子地比较并交换变量的值,确保值在交换前没有被修改。
*加载链接/存储条件存储(LL/SC):原子地加载一个值,并在存储一个值之前检查条件是否为真。
*内存屏障:强制指令按特定顺序执行,确保对共享内存的正确访问。
案例研究
在实际应用中,原子操作已被广泛用于实现线程安全的并发数据结构和算法。例如,在Java中,`AtomicInteger`类使用CAS操作来实现原子计数器,而`ConcurrentHashMap`类使用CAS和LL/SC操作来实现线程安全的散列表。
结论
原子操作是实现线程安全并发编程的重要工具。它们通过保证指令不可中断的执行,确保了共享数据的安全更新。与其他线程安全机制相比,原子操作具有线程安全、高性能、可伸缩性强和易于实现等优点。在需要确保多线程环境中数据一致性的场景中,原子操作是不可或缺的。第六部分延迟初始化的线程安全性关键词关键要点延迟初始化的线程安全性
主题名称:双重检查锁定
1.延迟初始化仅在需要时才初始化共享资源。
2.使用volatile关键字确保可见性,防止重排序导致的不完整初始化。
3.使用锁来防止多个线程同时初始化共享资源,确保原子性。
主题名称:可见性保障
延迟初始化的线程安全性
延迟初始化是一种针对并发数组进行线程安全初始化的技术,其核心思想是仅在需要时才初始化数组元素。通过这种方式,可以避免不必要的同步开销,从而提高性能。
实现原理
延迟初始化的并发数组通常通过以下机制实现:
*使用volatile域:数组的每个元素声明为volatile类型,以确保对元素的修改对所有线程可见。
*使用CAS循环:线程在初始化数组元素之前使用CAS(比较并交换)循环来检查元素是否已初始化。如果元素未初始化,则线程尝试使用CAS将其初始化为指定值。如果CAS操作成功,说明元素已成功初始化;否则,则表示另一个线程已在该元素上初始化,当前线程可以跳过初始化步骤。
*使用锁:为了确保CAS循环的原子性,使用锁来保护对元素的访问。当一个线程需要访问元素时,它会获取锁,然后执行CAS循环。这样可以确保在初始化过程中元素不会被其他线程修改。
优势
延迟初始化提供以下优势:
*提高性能:通过仅在需要时才初始化元素,可以避免在初始化过程中不必要的同步开销,从而提高性能。
*减少内存消耗:延迟初始化仅初始化实际使用的元素,因此可以减少内存消耗。
*提高可扩展性:延迟初始化不需要预先确定数组的大小,因此可以更轻松地扩展数组以适应不断变化的需求。
局限性
延迟初始化也有一些局限性:
*开销开销:虽然延迟初始化可以提高性能,但也需要引入CAS循环和锁开销,这在高并发环境中可能成为瓶颈。
*复杂性:实现延迟初始化的并发数组比直接初始化数组复杂,需要仔细考虑线程安全性问题。
*代码可读性:延迟初始化的代码可能比直接初始化的代码更难理解,因为涉及线程同步机制。
应用场景
延迟初始化的并发数组特别适用于以下场景:
*很少访问的数组:如果数组元素很少被访问,则延迟初始化可以显著降低初始化时间和内存消耗。
*大小动态的数组:对于大小动态变化的数组,延迟初始化可以避免预先分配过多或过少的内存。
*需要快速初始化的数组:对于需要快速初始化的数组,例如用于缓存或临时存储,延迟初始化可以减少初始化时间。
总结
延迟初始化是一种针对并发数组进行线程安全初始化的技术,通过仅在需要时才初始化元素来提高性能并减少内存消耗。虽然它有一些开销和复杂性,但它非常适合特定应用场景,例如很少访问的数组、大小动态的数组和需要快速初始化的数组。第七部分容器的线程安全初始化实践容器的线程安全初始化实践
前言
在并行编程中,共享数据结构的线程安全初始化至关重要,以避免竞态条件和数据损坏。对于并发数组(或集合、映射等其他数据结构),线程安全初始化涉及在多线程环境中安全地创建和填充数组。本文探讨容器线程安全初始化的最佳实践,以确保并发应用程序的正确性和可靠性。
并发数组的线程安全创建
*使用ConcurrentCollections:JavaConcurrency包提供了线程安全的集合类,如ConcurrentHashMap、CopyOnWriteArrayList和ConcurrentLinkedQueue。这些集合专为并发使用而设计,无需显式同步即可处理并发访问。
*使用Collections.synchronizedList:对于非线程安全的集合,可以使用Collections.synchronizedList()方法将其包装在一个同步包装器中。该包装器会在集合上的所有方法上施加锁,以确保原子访问。
*使用ReentrantLock:对于自定义集合或需要更精细控制的场景,可以使用ReentrantLock显式同步访问。ReentrantLock允许获得和释放锁,并提供等待和通知机制以处理并发。
并发数组填充的线程安全
在创建线程安全的并发数组后,下一步是安全地对其进行填充。以下是一些最佳实践:
*使用原子类:对于基本类型(如int、long、double),可以使用AtomicInteger、AtomicLong和AtomicDouble等原子类。这些类提供线程安全的增量和更新操作。
*使用volatile变量:对于引用类型,可以使用volatile变量。volatile变量会在每次读取或写入时强制刷新到主内存,确保所有线程看到最新值。
*使用并发队列:并发队列(如ConcurrentLinkedQueue)提供了线程安全的方式来添加和删除元素。队列内部处理并发访问,确保有序性和数据完整性。
*使用锁同步:对于自定义或非线程安全的集合,可以使用锁进行显式同步。可以在循环外部获得锁,然后在填充过程中保持锁持有。
避免竞态条件的最佳实践
除了线程安全初始化外,还应遵循以下最佳实践以避免竞态条件:
*使用不可变对象:尽量使用不可变对象,因为它们对并发访问是安全的。
*最小化锁持有时间:在使用显式锁时,应最小化锁持有时间。快速执行关键部分,并在不使用时及时释放锁。
*使用等待和通知:在某些情况下,使用等待和通知机制可以提高并发效率。这允许线程等待某个条件满足,然后继续执行。
*测试和验证:彻底测试并发代码至关重要,以发现和修复潜在的竞态条件。可以使用线程分析工具或并行调试器来帮助识别问题。
结论
线程安全初始化和并发数组填充是并发编程中的重要方面。通过遵循最佳实践,如使用线程安全集合、原子类、锁同步和避免竞态条件,可以确保并发应用程序的可靠性和正确性。这些实践对于设计和实现健壮且高效的并行代码至关重要。第八部分并发数组线程安全初始化的最佳实践并发数组线程安全初始化的最佳实践
选择正确的并发数组实现
*ConcurrentHashMap:哈希表实现,具有高效的并发查找和插入操作。
*ConcurrentLinkedQueue:队列实现,支持快速插入和删除,适合FIFO(先进先出)场景。
*CopyOnWriteArrayList:不可变列表实现,线程安全写入,但写入会产生新副本。
*AtomicInteger:原子整数值的封装,确保并发更新的线程安全性。
使用工厂方法创建
*使用工厂方法(如Collections.newConcurrentHashMap())创建并发数组,这可以确保正确初始化并应用任何必要な并行设置。
显式同步
*如果需要自定义初始化或更多的控制,可以使用显式同步(如锁或原子变量)来协调对并发数组的访问。
*注意:显式同步会影响性能,因此应谨慎使用。
不可变对象
*对于哈希表和队列等非线程安全的数据结构,请考虑使用不可变对象来确保线程安全性。
*例如,使用字符串的不可变版本而不是StringBuilder。
线程本地变量
*对于经常访问的并发数组,可以使用线程本地变量来提高性能。
*线程本地变量将每个线程的数组副本存储在自己的私有内存空间中,从而避免了对共享数组的锁定。
并发集合工具
*Java并发集合框架提供了一系列实用程序,可帮助初始化和管理线程安全数组。
*例如,ConcurrentHashMap.newKeySet()创建一个线程安全的哈希表键集。
测试和验证
*使用多线程测试用例彻底测试线程安全初始化。
*使用工具(如JUnit或TestNG)进行压力测试,以模拟现实世界的并发场景。
其他注意事项
*避免使用原生数组,因为它们不是线程安全的。
*考虑使用并行流或其他并发编程技术来提高初始化性能。
*定期监视并发数组的使用情况,以检测潜在的性能问题或线程安全性问题。
*遵守最佳实践并遵循Java并发编程指南,以确保并发数组的线程安全性。关键词关键要点趋势
1.数字资产的代币化:随着Web3.0的兴起,数字资产所有者将开始使用他们的代币或NFT进行交易或质押,以赚取Passive投资回报。
2.Web3.0上的社交代币:随着Web3.0的去中央化,社交代币将用于验证帐户的所有权和促进去中央化生态中的合作。
3.DeFi中的代币化:随着DeFI的成熟,代币将用于在去份布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布布
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 四川幼儿师范高等专科学校《大地测量学实验》2023-2024学年第二学期期末试卷
- 晋中师范高等专科学校《网络及其计算》2023-2024学年第二学期期末试卷
- 福建对外经济贸易职业技术学院《大学生劳动教育》2023-2024学年第二学期期末试卷
- 天津艺术职业学院《文献目录与信息检索》2023-2024学年第二学期期末试卷
- 2025海南省安全员A证考试题库及答案
- 贵州中医药大学时珍学院《安全经济学》2023-2024学年第二学期期末试卷
- 2024-2025学年辽宁省七校协作体高一上学期12月月考历史试卷
- 2025江西省建筑安全员-A证考试题库及答案
- 漯河医学高等专科学校《奥林匹克文化》2023-2024学年第二学期期末试卷
- 辽宁轻工职业学院《阿拉伯文学选读》2023-2024学年第二学期期末试卷
- 教科版 二年级下册科学教学计划
- 中国脓毒症及脓毒性休克急诊治疗指南
- 部编版六年级道德与法治下册《学会反思》教案
- 人教版体育与健康四年级-《障碍跑》教学设计
- DB32-T 2860-2015散装液体化学品槽车装卸安全作业规范-(高清现行)
- 部编版四年级下册语文教案(完整)
- T∕CIS 71001-2021 化工安全仪表系统安全要求规格书编制导则
- 福利院装修改造工程施工组织设计(225页)
- 环境空气中臭氧的测定
- 第七章 化学物质与酶的相互作用
- 机械毕业设计论文钢筋自动折弯机的结构设计全套图纸
评论
0/150
提交评论