Java_并發(fā)編程培訓(xùn)_第1頁
Java_并發(fā)編程培訓(xùn)_第2頁
Java_并發(fā)編程培訓(xùn)_第3頁
Java_并發(fā)編程培訓(xùn)_第4頁
Java_并發(fā)編程培訓(xùn)_第5頁
已閱讀5頁,還剩81頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、Java 并發(fā)編程龍浩在一個list中有過億條的Integer類型的值,如何更快的計算這些值的總和?一個計算的問題一個計算的問題簡單的方法:更快的CPU來遍歷靠譜的方法:分而治之來處理進一步的方法:Fork/jion簡單的方法靠譜么?簡單的方法靠譜么?免費午餐已經(jīng)結(jié)束免費午餐已經(jīng)結(jié)束軟件歷史性地向并發(fā)靠攏軟件歷史性地向并發(fā)靠攏http:/ 線程 并發(fā)編程(juc) 線程監(jiān)控工具編程思想和實踐 Fork/Jion框架Visibility:通過并發(fā)線程修改變量值, 必須將線程變量同步回主存后, 其他線程才能訪問到。Ordering:通過java提供的同步機制或volatile關(guān)鍵字, 來保證內(nèi)存的

2、訪問順序。Cache coherency :它是一種管理多處理器系統(tǒng)的高速緩存區(qū)結(jié)構(gòu),其可以保證數(shù)據(jù)在高速緩存區(qū)到內(nèi)存的傳輸中不會丟失或重復(fù)。 Happens-before ordering:synchronized,volatile,final,java.util.concurrent.lock|atomic線程:先讓路給內(nèi)存模型線程:先讓路給內(nèi)存模型這里有詳述:http:/is.gd/c8fhE (別迷戀哥,哥只是傳說!)內(nèi)存中的可見部分內(nèi)存中的可見部分Stack-1Stack-2Stack-3GlobalsHeap線程:線程:synchronized類同步方法同步塊同步內(nèi)部鎖分離鎖分拆鎖

3、保證原子性和可見性保證原子性和可見性線程:線程:Java MonitorsThis figure shows the monitor as three rectangles. In the center, a large rectangle contains a single thread, the monitors owner. On the left, a small rectangle contains the entry set. On the right, another small rectangle contains the wait set. Active threads ar

4、e shown as dark gray circles. Suspended threads are shown as light gray circles. 線程:獨占鎖(線程:獨占鎖(synchronized)l非方法修飾符,注意方法覆寫的時候需要加上synchronized;l經(jīng)典的順序鎖問題(兩個線程安全的方法放在一起線程安全么? )lgetClass的問題。l分拆前:思考問題,順便教你一招!分拆前:思考問題,順便教你一招!分拆不了人,工具還不能分拆么?對,買分拆不了人,工具還不能分拆么?對,買3個手機去個手機去線程:分拆鎖線程:分拆鎖線程:分離鎖線程:分離鎖分離鎖負面作用:對容器加

5、鎖,進行獨占訪問更加困難,并且更加昂貴了。內(nèi)存使用的問題:sina就曾經(jīng)因為在Action層使用ConcurrentHashMap而導(dǎo)致內(nèi)存使用過大,修改array后竟然單臺服務(wù)器節(jié)省2G。線程:線程:static的案例的案例public class StaticThreadTest /線程避免調(diào)用這個;public static Tree tree = new Tree(“jizi”,“2”);public static void createTree(Tree trees) Tree t = tree; if(trees.getName().equals(pg)t.setName(cesh

6、i);public static void main(String args) throws InterruptedExceptionExecutorService exec = Executors.newFixedThreadPool(10);for(int i=0;i10;i+) exec.execute(new TreeThread(i);Thread.sleep(50);exec.shutdown();exec.awaitTermination(1, TimeUnit.SECONDS);線程:可見性線程:可見性volatile關(guān)鍵字:1:簡化實現(xiàn)或者同步策略驗證的時候來使用它;2:確保

7、引用對象的可見性;3:標示重要的生命周期的事件,例如:開始或者關(guān)閉。脆弱的volatile的使用條件:1:寫入變量不依賴變量的當前值,或者能夠保證只有單一的線程修改變量的值;2:變量不需要和其他變量共同參與不變約束;3:訪問變量時不需要其他原因需要加鎖。private volatile boolean isInterrupted = false;任務(wù)的取消和線程超時任務(wù)的取消和線程超時線程中斷線程中斷教父教父Joshua Bloch說線程:說線程:1. 對共享可變數(shù)據(jù)同步訪問;2. 避免過多的同步;3. 永遠不要在循環(huán)外面調(diào)用wait;4. 不要依賴于線程調(diào)度器;5. 線程安全的文檔化;6.

8、避免使用線程組。目錄目錄 線程 并發(fā)編程(juc) 線程監(jiān)控工具編程思想和實踐 Fork/Jion框架開始并發(fā)編程了開始并發(fā)編程了行動之前,拜神先行動之前,拜神先1. Mr. concurrency ,當今世界上并發(fā)程序設(shè)計領(lǐng)域的先驅(qū),著名學(xué)者。他是util.concurrent包的作者,JSR166規(guī)范的制定。2. 圖書著作Concurrent Programming in Java: Design Principles and Patterns。3. 其” A Scalable Elimination-based Exchange Channel”和”Scalable Synchronou

9、s Queues”兩篇論文列為非阻塞同步算法的經(jīng)典文章。4. A fork/jion framework同樣影響著java7。Doug Lea并發(fā)編程:三大定律(并發(fā)編程:三大定律(1)討論的是加速比(speedup)的問題并發(fā)編程:三大定律(并發(fā)編程:三大定律(2)Gustafson假設(shè)隨著處理器個數(shù)的增加,并行與串行的計算總量也是可以增加的。Gustafson定律認為加速系數(shù)幾乎跟處理器個數(shù)成正比,如果現(xiàn)實情況符合Gustafson定律的假設(shè)前提的話,那么軟件的性能將可以隨著處理個數(shù)的增加而增加。并發(fā)編程:三大定律(并發(fā)編程:三大定律(3)充分利用存儲空間等計算資源,盡量增大問題規(guī)模以產(chǎn)生

10、更好/更精確的解??偨Y(jié)不是總結(jié)不是API,是寂寞!,是寂寞!來個高清無碼版來個高清無碼版ExecutorsExecutorExecutorServiceScheduledExecutorServiceCallableFutureScheduledFutureDelayedCompletionService ThreadPoolExecutor ScheduledThreadPoolExecutor AbstractExecutorService Executors FutureTask ExecutorCompletionServiceQueuesBlockingQueue Concurren

11、tLinkedQueue LinkedBlockingQueue ArrayBlockingQueue SynchronousQueue PriorityBlockingQueue DelayQueueConcurrent Collections ConcurrentMap ConcurrentHashMap CopyOnWriteArrayList,SetSynchronizers CountDownLatch Semaphore Exchanger CyclicBarrierTiming TimeUnitLocks Lock Condition ReadWriteLock Abstract

12、QueuedSynchronizer LockSupport ReentrantLock ReentrantReadWriteLockAtomics AtomicType, AtomicTypeArray AtomicTypeFieldUpdater AtomicMarkable,StampableReferenceThreadPoolExecutorThreadPoolExecutor:自己動手,豐衣足食?。鹤约簞邮郑S衣足食! public static ExecutorService newFixedThreadPool(int nThreads) return new ThreadPo

13、olExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue(); 1:線程池的大小最好是設(shè)定好,因為JDK的管理內(nèi)存畢竟是有限的;2:使用結(jié)束,需要關(guān)閉線程池;3: Runtime.getRuntime().addShutdownHook(hook); 對不能正常關(guān)閉的線程做好相關(guān)的記錄。Executors:ExecutorServiceExecutorService嚴重注意:別設(shè)置線程池?zé)o限大小入門版:入門版:CompletionService生產(chǎn)者消費者模式的簡要實現(xiàn)版本。生產(chǎn)者消費者模

14、式的簡要實現(xiàn)版本。雙劍合璧:雙劍合璧:Future+Callable任務(wù)池: ScheduledExecutorServiceTimer+TimeTasTimer+TimeTask kScheduledExecScheduledExecutorServcieutorServcie + + DelayQeuueDelayQeuueQuartzQuartz計劃任務(wù)執(zhí)行相關(guān)的操作,使用使用java真幸福,選擇多多!真幸福,選擇多多!阻塞隊列:阻塞隊列:BlockingQueue拋出異常特殊值阻塞超時插入插入add(e)offer(e)put(e)offer(e, time, unit)移除移除rem

15、ove()poll()take()poll(time, unit)檢查檢查element()peek()不可用不可用Kaopuability:插入(offer);移除(poll)BlockingQueue 的諸侯領(lǐng)地的諸侯領(lǐng)地接口抽象類子類BlockingQueueAbstractQueueArrayBlockingQueueDelayQueueLinkedBlockingDequeLinkedBlockingQueuePriorityBlockingQueueSynchronousQueueArrayBlockingQueue:一個由數(shù)組支持的有界阻塞隊列。此隊列按 FIFO(先進先出)原則

16、對元素進行排序。Delayed 元素的一個無界阻塞隊列,只有在延遲期滿時才能從中提取元素.LinkedBlockingDeque一個基于已鏈接節(jié)點的、任選范圍的阻塞雙端隊列。 LinkedBlockingQueue一個基于已鏈接節(jié)點的、范圍任意的 blocking queue。此隊列按 FIFO(先進先出)排序元素PriorityBlockingQueue一個無界阻塞隊列,它使用與類 PriorityQueue 相同的順序規(guī)則,并且提供了阻塞獲取操作。SynchronousQueue一種阻塞隊列,其中每個插入操作必須等待另一個線程的對應(yīng)移除操作 ,反之亦然。BlockingDeque:雙端隊列

17、雙端隊列第一個元素(頭部)第一個元素(頭部)拋出異常特殊值阻塞超時期插入插入addFirst(e)offerFirst(e)putFirst(e)offerFirst(e, time, unit)移除移除removeFirst() pollFirst()takeFirst()pollFirst(time, unit)檢查檢查getFirst()peekFirst()不適用不適用最后一個元素(尾部)最后一個元素(尾部)拋出異常特殊值阻塞超時期插入插入addLast(e)offerLast(e)putLast(e)offerLast(e, time, unit)移除移除removeLast() p

18、ollLast()takeLast()pollLast(time, unit)檢查檢查getLast()peekLast()不適用不適用并發(fā)集合并發(fā)集合:你值得擁有你值得擁有同步的不是同步的不是Map,是鳳姐!是鳳姐!ConcurrentHashMap:解放軍解放軍38軍軍你那飄逸的同步,分離鎖的設(shè)計,再hash算法以及游離于多個Segment的耍心跳的各種操作,都深深的吸引了我。詳細設(shè)計細節(jié):http:/ List array = new ArrayList();public List list = new CopyOnWriteArrayList(array);同步器:四大金剛同步器:四大

19、金剛閉鎖:閉鎖:CountDownLatch等待啟動信號線程A獲得等待啟動信號線程B獲得等待啟動信號線程C獲得等待啟動信號線程A運行,遞減鎖存器的計數(shù)線程B運行,遞減鎖存器的計數(shù)線程C運行,遞減鎖存器的計數(shù)等待完成信號繼續(xù)啟動信號+完成信號的模式N部分鎖存器倒計數(shù)模式;當線程必須用這種方法反復(fù)倒計數(shù)時,可改為使用 CyclicBarrier典型應(yīng)用:手動控制事務(wù),從數(shù)據(jù)庫讀取多份數(shù)據(jù)做初始化;典型應(yīng)用:手動控制事務(wù),從數(shù)據(jù)庫讀取多份數(shù)據(jù)做初始化;關(guān)卡:關(guān)卡:CyclicBarrierBarrierABCABCBarrierBarrierABCA barrierA barrier: A barr

20、ier is a coordination mechanosm (an algorithm) that forces process which participate in a concurrent (or distributed) algorithm to wait until each one of them has reached a certain point in its program. The collection of these coordination points is called the barrier. Once all the processes have re

21、ached the barrier, they are all permitted to continue past the barrier. 信號量:信號量:Semaphore運行后釋放信號(release();)線程C線程A線程B獲取信號( acquire();)交換器:交換器:Exchanger1. 數(shù)據(jù)分解和數(shù)據(jù)流分解的一種技巧,可被視為 SynchronousQueue 的雙向形式。2. JDK5時支持2個線程之間交換數(shù)據(jù),JDK6后支持多個。至今我沒有用過鎖云:你的柔情我永遠不懂鎖云:你的柔情我永遠不懂內(nèi)部鎖互斥鎖分離鎖分拆鎖閉鎖獨占鎖讀寫鎖順序鎖互斥鎖:互斥鎖: Reentran

22、tLockLock 更加靈活,性能更好interface Lock void lock();void lockInterruptibly() throws InterruptedException;boolean tryLock();boolean tryLock(long timeout, TimeUnit unit)throws InterruptedException;void unlock();Condition newCondition();支持多個Condition可以不以代碼塊的方式上鎖可以使用tryLock,并指定等待上鎖的超時時間調(diào)試時可以看到內(nèi)部的owner thread,

23、方便排除死鎖RenntrantLock支持fair和unfair兩種模式互斥鎖(公平與非公平)和內(nèi)部鎖性能對比圖互斥鎖(公平與非公平)和內(nèi)部鎖性能對比圖02000400060008000100001200014000200/200200/500200/1000200/1500200/2000500/200500/500500/1000500/1500500/2000內(nèi)部鎖非公平互斥鎖公平互斥鎖原子操作結(jié)論:非公平互斥鎖和內(nèi)部鎖性能在結(jié)論:非公平互斥鎖和內(nèi)部鎖性能在jdk6_17jdk6_17下性能基本一樣。下性能基本一樣。測試機:酷睿2.66雙核,2G內(nèi)存,win7讀寫鎖:讀寫鎖: ReadW

24、riteLockReadWriteLock 維護了一對相關(guān)的鎖,一個用于只讀操作,另一個用于寫入操作。只要沒有 writer,讀取鎖可以由多個 reader 線程同時保持。寫入鎖是獨占的。ReentrantReadWriteLockReadLock WriteLock A線程B線程C線程線程1線程2線程3高深:高深:AbstractQueuedSynchronizerl為實現(xiàn)依賴于先進先出 (FIFO) 等待隊列的阻塞鎖和相關(guān)同步器(信號量、事件,等等)提供一個框架;l基于JDK底層來操控線程調(diào)度,LockSupport.park和LockSupport.unpark;l此類支持默認的獨占 模

25、式和共享 模式之一,或者二者都支持;l如果想玩玩它,請看CountDownLatch的源碼。l當然,也可以去FutureTask這個類看看。目錄目錄 線程 并發(fā)編程(juc) 線程監(jiān)控工具編程思想和實踐 Fork/Jion框架Fork/Join Framework (1)Work StealingFork/Join FrameworklFJTask框架是Cilk用到的設(shè)計方案的變體,相關(guān)系統(tǒng)依賴于輕量級可執(zhí)行任務(wù)。這些框架都是像操作系統(tǒng)映射線程到CPU一樣來映射任務(wù)到線程,從而開發(fā)單純,有規(guī)律,有約束力的fork/join程序來執(zhí)行映射動作。l工作線程池是確定的,每個工作線程(Thread子類

26、FJTaskRunner的一個實例)是處理隊列中任務(wù)的標準線程。正常的,工作線程的數(shù)量和系統(tǒng)的CPU的數(shù)量是一致的。任何合乎情理的映射策略將把這些線程映射到不同的cpu。l所有的fork/join任務(wù)都是一個輕量級可執(zhí)行類的實例,不是一個線程實例。在java中,獨立的可執(zhí)行任務(wù)必須實現(xiàn)Runnable接口并定義一個run()方法。在FJTask框架中,這些任務(wù)是FJTask的子類而不是Thread的子類,它們都實現(xiàn)了Runnable接口l一個簡單的控制和管理設(shè)施(這里講的是FJTaskRunnerGroup)設(shè)置工作池,從一個正常的線程(例如java語言中的main()方法)調(diào)用啟動執(zhí)行提供的

27、fork/join任務(wù)。Doug Lea論文:/dl/papers/fj.pdfFork/Join 的案例:求數(shù)組中的最大值的案例:求數(shù)組中的最大值Fork/Join 運行測試結(jié)果運行測試結(jié)果闕值 = 500k闕值 = 50k闕值 = 5k闕值 = 500闕值 = -50Pentium-4 HT(2 個線程)1.01.071.02.82.2Dual-Xeon HT(4 個線程).883.038-way Opteron(8 個線程)1.05.295.734.532.038-core Niagara(32 個線程).9810.461

28、7.2115.346.49表表 1. 在不同系統(tǒng)上從在不同系統(tǒng)上從 500k 個元素的數(shù)組中運行個元素的數(shù)組中運行 select-max 的結(jié)果的結(jié)果fork-join 池中的線程數(shù)量與可用的硬件線程(內(nèi)核數(shù)乘以每個內(nèi)核中的線程數(shù))相等Fork/Join 有用的資源有用的資源表表 1. 在不同系統(tǒng)上從在不同系統(tǒng)上從 500k 個元素的數(shù)組中運行個元素的數(shù)組中運行 select-max 的結(jié)果的結(jié)果jsr166:/dl/concurrency-interest/index.htmlJava 理論與實踐: 應(yīng)用 fork-join 框架:Brian G

29、oetzhttp:/ 7 中的 Fork/Join 模式http:/ 線程 并發(fā)編程(juc) 線程監(jiān)控工具編程思想和實踐 Fork/Jion框架線程監(jiān)控:線程監(jiān)控:DIYKill -3unixviWindows 下面DIY方式很多,txt編輯器都是好東西線程監(jiān)控:線程監(jiān)控:Jconsole線程監(jiān)控:線程監(jiān)控:VisualVm本地本地下載地址:https:/ Dump Analyzerhttps:/ 線程 并發(fā)編程(juc) 線程監(jiān)控工具 編程思想和實踐 Fork/Jion框架基本思想:基本思想:CAS操作操作 處理器指令,全稱Compare and swap,原子化的讀-該-寫指令 處理競爭

30、策略:單個線程勝出,其他線程失敗,但不會掛起基本思想:基本思想:Atomic原子類原子類 基于硬件CAS實現(xiàn)Atomic類 分四組:計量器、域更新器、數(shù)組、復(fù)合變量 更佳的volatile 目標1:實現(xiàn)復(fù)雜算術(shù)運算:incrementAndGet、getAndIncrement等 目標2:支持Java類型對象的CAS操作:compareAndSet基本思想:非阻塞算法基本思想:非阻塞算法 一個線程的失敗或掛起不影響其他線程 J.U.C的非阻塞算法依賴Atomic 算法里一般采用回退機制處理Atomic的CAS競爭 對死鎖免疫的同步機制 目標:相對阻塞算法,減少線程切換開銷、減少鎖的競爭等。 也

31、是Lock-free,即無鎖編程無鎖棧算法:無鎖棧算法:Treiber算法改進版:http:/ M S - q u e u e 算法是1 9 9 6 年由M a g e d . M .Michael and M. L. Scott提出的,是最為經(jīng)典的并發(fā)FIFO隊列上的算法,目前很多對并發(fā)FIFO隊列的研究都是基于這個算法來加以改進的。 MS-queue算法的隊列用一個單鏈表來實現(xiàn),包含兩個基本的操作,enquene()和dequene() ,新節(jié)點總是從隊尾最后一個元素后面加入隊列,節(jié)點元素總是從隊頭刪除。包含兩個指針,head和tail,head總是自相鏈表頭部的節(jié)點,指向的這個節(jié)點被當作

32、是啞節(jié)點或哨兵節(jié)點,它保存的值是多少并無意義;tail總是指向鏈表中的一個節(jié)點,不一定是隊尾元素。每個節(jié)點包含兩個數(shù)據(jù)域值信息,即存放的數(shù)值信息和指向下一個節(jié)點的指針。每個指針對象,除了包含一個指向節(jié)點的指針外,還包含一個時間戳,初試時時戳為零,每修改一次指針,時戳增加一,在64位系統(tǒng)中,無需考慮時戳溢出的影響。無鎖隊列算法:無鎖隊列算法:Optitmistic算法 Optimistic算法對于上面提到的MS-queue算法的改進就在于使用普通的store指令代替代價昂貴的CAS指令。 Optimistic算法的高效性在于使用雙向鏈表表示隊列,并且入隊和出隊操作都只需要一次成功的CAS操作。該

33、算法保證鏈表總是連接的,next指針總是一致的,當prev指針出現(xiàn)不一致時通過調(diào)用fixList方法能夠恢復(fù)到一致性狀態(tài)。 同MS-queue算法一樣,optimistic算法也用到了原子化的指令Compare-and-swap(CAS),CAS(a,p,n),原子化的將內(nèi)存地址a中的值與p進行比較,如果二者相等,就將n寫入地址a中并返回true,否則返回false。由于optimistic算法使用了CAS指令,所以經(jīng)典的ABA問題同樣會出現(xiàn),解決方案同MS-queue相同,即使用標簽機制。論文地址:/soft/L17_Fober.pdfAto

34、mic實現(xiàn)實現(xiàn)public final int incrementAndGet() for (;) int current = get(); int next = current + 1; if (compareAndSet(current, next) return next; public final boolean compareAndSet(int expect, int update) return pareAndSwapInt(this, valueOffset, expect, update); 當 import sun.misc.Unsafe; 這個的時候,就因為各種問題(例如

35、:專利)看不到源碼了。好東東:好東東:AtomicReferenceLock-free的數(shù)據(jù)結(jié)構(gòu)就靠這個了,無論你喜歡與否,玩無鎖編程,你都繞不開這個類??碼mino框架的源碼,你會發(fā)現(xiàn)這個妞無處不在。當然,還是AtomicInteger比較實用,多線程計數(shù)的時候,你會喜歡的。編程實踐:使用更優(yōu)的鎖編程實踐:使用更優(yōu)的鎖編程實踐:使用更優(yōu)的鎖編程實踐:使用更優(yōu)的鎖ReentrantLock比較內(nèi)部鎖在JDK的性能提升對比編程實踐:使用更優(yōu)的鎖編程實踐:使用更優(yōu)的鎖讀寫鎖對比互斥鎖ReentrantLock的性能編程實踐:縮小鎖的范圍編程實踐:縮小鎖的范圍 減少線程把持鎖的時間 避免在臨界區(qū)進行

36、耗時計算 常見做法:縮小同步快 常見做法:把一個同步塊分拆成多個 需要保證業(yè)務(wù)邏輯正確為前提編程實踐:避免熱點域編程實踐:避免熱點域 熱點域:每次操作,都需要訪問修改的fields eg. ConcurrentHashMap的size計算問題編程實踐:編程實踐:使用不變和使用不變和Thread Local 的數(shù)據(jù)的數(shù)據(jù) 不變數(shù)據(jù),即Immutable類型數(shù)據(jù)、在其生命周期中始終保持不變,可以安全地在每個線程中復(fù)制一份以便快速讀取。 ThreadLocal數(shù)據(jù),只被線程本身使用,因此不存在不同線程之間的共享數(shù)據(jù)的問題。編程實踐:編程實踐:使用高并發(fā)容器使用高并發(fā)容器 J.U.C的高效地線程安全的

37、并發(fā)容器 Amino提供更多非阻塞的容器編程實踐:編程實踐:高速緩存計算結(jié)果高速緩存計算結(jié)果 利用空間換時間 避免了重復(fù)計算相同的數(shù)據(jù)編程實踐:編程實踐:文檔化對外接口的同步策略文檔化對外接口的同步策略 如果一個類沒有明確指明,就不要假設(shè)它是線程安全的編程實踐:編程實踐:安全發(fā)布安全發(fā)布NotThreadSafepublic class UnsafeLazyInitialization private static Resource resource; public static Resource getInstance() if (resource = null) resource = new Resource(); / unsafe publication return resource; ThreadSafepublic class

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論