作????者 | 朱福喜 | 出版社 | 第1版 (2005年10月1日) |
---|---|---|---|
出版時(shí)間 | 2005年10月 | 頁(yè)????數(shù) | 314 頁(yè) |
定????價(jià) | 38.0 | 裝????幀 | 平裝 |
ISBN | 9787121016141 |
內(nèi)容介紹
既保證有一定的實(shí)用性,同時(shí)也要確保一定的廣度和深度。在應(yīng)用這些技術(shù)的同時(shí),還涉及到Access、MySQL等數(shù)據(jù)庫(kù)系統(tǒng)、Tomcat應(yīng)用服務(wù)器,以及Intemet的相關(guān)技術(shù)。
2100433B
秸稈煤炭成型機(jī)是指以農(nóng)村的玉米秸稈、小麥秸稈、棉花桿、稻草、稻殼、花生殼、玉米芯、樹(shù)枝、樹(shù)葉、鋸末等農(nóng)作物、固體廢棄物為原料,經(jīng)過(guò)粉碎后加壓、增密成型的秸稈炭的全套機(jī)械化生產(chǎn)設(shè)備。秸稈煤炭成型機(jī)性能好...
政府項(xiàng)目設(shè)計(jì)費(fèi)怎么算
根據(jù)相關(guān)法律規(guī)定,這設(shè)計(jì)費(fèi)都是有公式計(jì)算的,你可以上網(wǎng)查一下或咨詢(xún)相關(guān)人員。 工程勘察設(shè)計(jì)收費(fèi)管理規(guī)定 計(jì)價(jià)格[2002]10號(hào)? ?第一條?為了規(guī)范工程勘察設(shè)計(jì)收費(fèi)行為,維護(hù)發(fā)包人和勘察人、設(shè)計(jì)人的...
為了更好地定制廈門(mén)地標(biāo),世茂攜手的設(shè)計(jì)單位是中國(guó)第一高樓、上海中心的建筑設(shè)計(jì)團(tuán)隊(duì)——— GENSLER事務(wù)所美國(guó)。他們把兩幢250米 的高樓設(shè)計(jì)成美麗的“風(fēng)帆”,融入了廈門(mén)市花“三角梅”的視覺(jué)元素,想...
格式:pdf
大小:101KB
頁(yè)數(shù): 未知
評(píng)分: 4.5
\"男裝項(xiàng)目設(shè)計(jì)開(kāi)發(fā)\"是一門(mén)綜合性實(shí)踐課程,它強(qiáng)調(diào)知識(shí)、能力、素質(zhì)之間的相互轉(zhuǎn)化,突出藝工結(jié)合的專(zhuān)業(yè)特點(diǎn),開(kāi)設(shè)這門(mén)課程的目的是促進(jìn)學(xué)生設(shè)計(jì)、工程技術(shù)等綜合實(shí)踐能力的提高。通過(guò)優(yōu)化教學(xué)內(nèi)容、實(shí)施多樣化的教學(xué)方法以及改革考核評(píng)價(jià)體系,對(duì)\"男裝項(xiàng)目設(shè)計(jì)開(kāi)發(fā)\"課的教學(xué)進(jìn)行有益的探索與實(shí)踐。
格式:pdf
大?。?span id="hx1te2e" class="single-tag-height">101KB
頁(yè)數(shù): 2頁(yè)
評(píng)分: 4.5
我國(guó)房地產(chǎn)開(kāi)發(fā)建設(shè)項(xiàng)目設(shè)計(jì)過(guò)程一般可分為兩個(gè)大階段:方案設(shè)計(jì)階段和施工圖設(shè)計(jì)階段。這兩個(gè)階段的成果必須報(bào)政府部門(mén)審批通過(guò),方可進(jìn)行工程項(xiàng)目施工。可以認(rèn)為建設(shè)項(xiàng)目設(shè)計(jì)過(guò)程的項(xiàng)目管理是圍繞著這兩個(gè)最終成果而展開(kāi)的。由于這兩個(gè)設(shè)計(jì)階段所承擔(dān)的目標(biāo)和任務(wù)的不同,其項(xiàng)目設(shè)計(jì)管理在執(zhí)行組織的結(jié)構(gòu)、項(xiàng)目不同形式的管理及質(zhì)量管理等方面存在著較大差異。對(duì)于房地產(chǎn)開(kāi)發(fā)實(shí)施階段的變更管理,設(shè)計(jì)變更是由兩方面因素造成的:一方面是由設(shè)計(jì)團(tuán)隊(duì)整體的水平、能力、素質(zhì)決定的,所以選擇設(shè)計(jì)團(tuán)隊(duì)是控制設(shè)計(jì)變更最有效的方法之一;另一方面是房地產(chǎn)公司管理團(tuán)隊(duì)的水平、能力、素質(zhì)決定的,如公司相關(guān)管理部門(mén)編制的策劃書(shū)、設(shè)計(jì)委托書(shū)科學(xué)、準(zhǔn)確,具有一定的前瞻性,那么就能非常好的控制設(shè)計(jì)變更的數(shù)量,從而達(dá)到控制工期和造價(jià)。
JavaWeb應(yīng)用開(kāi)發(fā)框架實(shí)例
一、 概述
Web 應(yīng)用架構(gòu)可以劃分為兩大子系統(tǒng):前端子系統(tǒng)和后臺(tái)子系統(tǒng)。
前端子系統(tǒng):
1. 基礎(chǔ)技術(shù): Html/Java/CSS / Flash
2. 開(kāi)發(fā)框架: jQuery, Extjs , Flex 等;
后臺(tái)子系統(tǒng):
1. 基礎(chǔ)技術(shù): Java Servlet;
2. 開(kāi)發(fā)框架: Struts, Spring, Hibernate, ibatis 等;
3. 應(yīng)用服務(wù)器: Tomcat / Jetty
編程模型: B/S 模型。 客戶(hù)端向服務(wù)器端發(fā)送請(qǐng)求, 服務(wù)器經(jīng)過(guò)處理后返回響應(yīng), 然后客戶(hù)端根據(jù)響應(yīng)及需求繪制前端展現(xiàn)。
在用戶(hù)客戶(hù)端和實(shí)際提供功能的Web 服務(wù)器之間還可能存在著代理服務(wù)器, 負(fù)載均衡服務(wù)器, 不過(guò)那些屬于錦上添花的事物,暫時(shí)不在考慮范圍內(nèi)。
客戶(hù)端應(yīng)用理念: 客戶(hù)端承擔(dān)大量的交互邏輯及渲染工作,服務(wù)器端主要是處理請(qǐng)求和返回?cái)?shù)據(jù)。
前后端系統(tǒng)耦合: 客戶(hù)端和服務(wù)器端各自處理自己內(nèi)部的子系統(tǒng)耦合;而客戶(hù)端與服務(wù)器端的耦合簡(jiǎn)化為一個(gè)通信與數(shù)據(jù)通道。該通道用來(lái)傳輸通信請(qǐng)求和返回?cái)?shù)據(jù)。
請(qǐng)求通信: 采用 Http / Tcp 協(xié)議
數(shù)據(jù)通道: 采用 Json, xml , 文本字符串,字節(jié)。 內(nèi)部系統(tǒng)一般采用 Json 作為數(shù)據(jù)交換格式;系統(tǒng)間的互操作則采用XML 來(lái)規(guī)范;文本字符串是最一般的形式, 字節(jié)是最底層的形式。
JavaWeb應(yīng)用開(kāi)發(fā)框架實(shí)例
二、 架構(gòu)演變
最輕的架構(gòu): jQuery + Servlet + ajax 在客戶(hù)端使用 jQuery發(fā)送 ajax 請(qǐng)求給Java 服務(wù)端的 Servlet 進(jìn)行處理, Servlet 僅僅返回?cái)?shù)據(jù)給客戶(hù)端進(jìn)行渲染。
該架構(gòu)有效地分離了前端展示和后臺(tái)請(qǐng)求處理,同時(shí)又保持了最輕的復(fù)雜性, 只需要學(xué)會(huì)編寫(xiě) Servlet 及使用 jQuery , 就能構(gòu)建簡(jiǎn)單的應(yīng)用。
如果只是做個(gè)人創(chuàng)意演示, 可以采用該架構(gòu), 快速實(shí)現(xiàn)自己的創(chuàng)意功能。 Servlet 是Java web 應(yīng)用的基礎(chǔ)技術(shù),jQuery 則是前端開(kāi)發(fā)的簡(jiǎn)單易用的利器。
后臺(tái)架構(gòu)演變:
1. 邏輯與頁(yè)面的分離: JSP/Servlet
JSP 實(shí)現(xiàn)了頁(yè)面邏輯與外觀(guān)的分離,但是, 前端子系統(tǒng)與后臺(tái)子系統(tǒng)仍然是緊密耦合的; 前端設(shè)計(jì)人員實(shí)際上只需要服務(wù)端返回的數(shù)據(jù), 就可設(shè)計(jì)出非常專(zhuān)業(yè)的界面顯示。
2. MVC 架構(gòu):Struts2(含Servlet,MVC) + JDBC
用Servlet 來(lái)添加服務(wù)器功能是基本的選擇,但在web.xml中配置大量的 Servlet 卻不是最佳的選擇。
Struts2 在服務(wù)端實(shí)現(xiàn)了更豐富的MVC 模式, 將本來(lái)由應(yīng)用決定的控制器從web容器中分離。
3. SSH 架構(gòu): Struts2(含Servlet, MVC) + Spring (Ioc) + Hibernate (ORM,對(duì)象-關(guān)系映射)
通常, 應(yīng)用系統(tǒng)中需要預(yù)先創(chuàng)建一些單例對(duì)象, 比如 Controller, Service, Dao, 線(xiàn)程池等, 可以引入 Spring Ioc 來(lái)有效地創(chuàng)建、管理和推送這些對(duì)象;使用 Hibernate 來(lái)實(shí)現(xiàn)關(guān)系數(shù)據(jù)庫(kù)的行與面向?qū)ο蟮膶傩灾g的映射與聯(lián)接,以更好地簡(jiǎn)化和管理應(yīng)用系統(tǒng)的數(shù)據(jù)庫(kù)操作。SSH 可以說(shuō)是 JavaWeb應(yīng)用系統(tǒng)開(kāi)發(fā)的三劍客。
4. SI 架構(gòu): SpringMVC(含Servlet, Ioc, MVC, Rest) + iBatis (Semi-ORM)
過(guò)于復(fù)雜的架構(gòu)會(huì)將人搞暈。因此,在適應(yīng)需求的情況下, 盡量選擇簡(jiǎn)單的架構(gòu),是明智之選。 這種架構(gòu)使用面向資源的理念,著重使用Spring作為MVC及應(yīng)用基礎(chǔ)服務(wù)設(shè)施, 同時(shí)使用 iBatis 來(lái)實(shí)現(xiàn)更簡(jiǎn)單靈活的ORM映射, 使之在可以理解和維護(hù)的范圍內(nèi)。
前端架構(gòu):
1. Flash 架構(gòu): Flex + jQuery + JSP
這是一種比較傳統(tǒng)的前端架構(gòu),采用同步模式, Flex 承擔(dān)大量的頁(yè)面渲染工作, 并采用AMF協(xié)議與Java端進(jìn)行通信, 而JSP 則可以用于更快速的頁(yè)面顯示。優(yōu)點(diǎn)是: 經(jīng)過(guò)考驗(yàn)的結(jié)構(gòu), 通常是值得信賴(lài)的; 缺點(diǎn)是, 由于采用同步模式, 在交互效果上可能不夠流暢, 需要進(jìn)行比較耗時(shí)的編譯過(guò)程;此外, Flex 基于瀏覽器插件運(yùn)行,在調(diào)試方面有些麻煩。
2. MVC 架構(gòu): Extjs + jQuery
這是一種比較現(xiàn)代的前端架構(gòu), 采用異步模式, Extjs4 可以實(shí)現(xiàn)前端子系統(tǒng)的MVC 分離, 對(duì)于可維護(hù)性是非常不錯(cuò)的支持;此外, jQuery 可以作為有效的補(bǔ)充。
優(yōu)點(diǎn): 異步, 快速, 對(duì)于企業(yè)內(nèi)部的后臺(tái)管理系統(tǒng)是非常好的選擇。
缺點(diǎn): Extjs4 的可定制性、可適應(yīng)性可能難以適應(yīng)各種特殊的需求,需要用其它組件來(lái)補(bǔ)充, 比如大數(shù)據(jù)量的繪制。對(duì)于互聯(lián)網(wǎng)應(yīng)用, 速度可能是致命傷。
三、 架構(gòu)的選擇
不要去詢(xún)問(wèn)哪種架構(gòu)更好,更需要做的是清晰地定位項(xiàng)目目標(biāo),根據(jù)自己的具體情況來(lái)選擇和定制架構(gòu)。反復(fù)地嘗試、觀(guān)察和改進(jìn),反復(fù)磨煉技藝,這樣才有助于設(shè)計(jì)水平的提升。
架構(gòu)的選擇通常有四種關(guān)注點(diǎn):
1. 適用性: 是否適合你的項(xiàng)目需求。 架構(gòu)有大有小, 小項(xiàng)目用小架構(gòu), 大項(xiàng)目用大架構(gòu)。
2. 可擴(kuò)展性: 該架構(gòu)在需要添加新功能時(shí),是否能夠以常量的成本添加到現(xiàn)有系統(tǒng)中, 所做的改動(dòng)在多大程度上會(huì)影響現(xiàn)有功能的實(shí)現(xiàn)(基本不影響,還是要大面積波及)。
3. 便利性: 使用該架構(gòu)是否易于開(kāi)發(fā)功能和擴(kuò)展功能, 學(xué)習(xí)、開(kāi)發(fā)和測(cè)試成本有多大。
4. 復(fù)雜性: 使用該架構(gòu)后,維護(hù)起來(lái)的成本有多大。你自然希望能夠?qū)懸粭l語(yǔ)句做很多事,使用各種成熟的組件是正確的方式,同時(shí),在項(xiàng)目中混雜各種組件,也會(huì)提升理解和維護(hù)系統(tǒng)的復(fù)雜度。便利性和復(fù)雜性需要達(dá)到較好的平衡。
特殊的關(guān)注點(diǎn):
譬如,應(yīng)用需要支持高并發(fā)的情況, 需要建立一個(gè)底層的并發(fā)基礎(chǔ)設(shè)施, 并向上層提供簡(jiǎn)單易用的接口,屏蔽其復(fù)雜性。
四、 架構(gòu)演進(jìn)的基本手段
架構(gòu)并不是一成不變的, 在做出最初的架構(gòu)之后,隨著開(kāi)發(fā)的具體情況和需求的變更, 需要對(duì)最初架構(gòu)做出變更和改進(jìn)。
架構(gòu)演進(jìn)的基本手段:
一致性, 隔離與統(tǒng)一管理, 螺旋式重構(gòu)改進(jìn), 消除重復(fù), 借鑒現(xiàn)有方案。
1. 一致性: 確保使用統(tǒng)一模式來(lái)處理相同或相似的功能; 解決一次, 使用多次。
2. 模塊化、隔離與統(tǒng)一管理: 對(duì)于整體的應(yīng)用, 分而治之,將其劃分為隔離性良好的模塊,提供必要的通信耦合;對(duì)于特定的功能模塊, 采用隔離手段,將其隔離在局部統(tǒng)一管理,避免分散在系統(tǒng)的各處。
3. 不斷重構(gòu)改進(jìn), 一旦發(fā)現(xiàn)更好的方式, 馬上替換掉原有方式。
4. 盡可能重用,消除重復(fù)。
5. 盡可能先借鑒系統(tǒng)中已有方案并復(fù)用之;如果有更好方案可替換之;
有一條設(shè)計(jì)準(zhǔn)則是: 預(yù)先設(shè)計(jì), 但不要過(guò)早設(shè)計(jì)。
意思是說(shuō), 需要對(duì)需求清楚的部分進(jìn)行仔細(xì)的設(shè)計(jì), 但是對(duì)于未知不清楚的需求,要堅(jiān)持去理解它,但不要過(guò)早地去做出“預(yù)測(cè)性設(shè)計(jì)”;設(shè)計(jì)必須是明確的、清晰的、有效的, 不能針對(duì)含糊的東西來(lái)設(shè)計(jì)??梢栽诤笃谕ㄟ^(guò)架構(gòu)演進(jìn)來(lái)獲得對(duì)后續(xù)需求的適應(yīng)能力。
編譯:伯樂(lè)在線(xiàn) - 范琦琦
死鎖是兩個(gè)甚至多個(gè)線(xiàn)程被永久阻塞時(shí)的一種運(yùn)行局面,這種局面的生成伴隨著至少兩個(gè)線(xiàn)程和兩個(gè)或者多個(gè)資源。在這里我已寫(xiě)好一個(gè)簡(jiǎn)單的程序,它將會(huì)引起死鎖方案然后我們就會(huì)明白如何分析它。
Java死鎖范例
ThreadDeadlock.java
package com.journaldev.threads;
public class ThreadDeadlock {
public static void main(String[] args) throws InterruptedException {
Object obj1 = new Object();
Object obj2 = new Object();
Object obj3 = new Object();
Thread t1 = new Thread(new SyncThread(obj1, obj2), "t1");
Thread t2 = new Thread(new SyncThread(obj2, obj3), "t2");
Thread t3 = new Thread(new SyncThread(obj3, obj1), "t3");
t1.start();
Thread.sleep(5000);
t2.start();
Thread.sleep(5000);
t3.start();
}
}
class SyncThread implements Runnable{
private Object obj1;
private Object obj2;
public SyncThread(Object o1, Object o2){
this.obj1=o1;
this.obj2=o2;
}
@Override
public void run() {
String name = Thread.currentThread().getName();
System.out.println(name + " acquiring lock on "+obj1);
synchronized (obj1) {
System.out.println(name + " acquired lock on "+obj1);
work();
System.out.println(name + " acquiring lock on "+obj2);
synchronized (obj2) {
System.out.println(name + " acquired lock on "+obj2);
work();
}
System.out.println(name + " released lock on "+obj2);
}
System.out.println(name + " released lock on "+obj1);
System.out.println(name + " finished execution.");
}
private void work() {
try {
Thread.sleep(30000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
在上面的程序中同步線(xiàn)程正完成Runnable的接口,它工作的是兩個(gè)對(duì)象,這兩個(gè)對(duì)象向?qū)Ψ綄で笏梨i而且都在使用同步阻塞。
在主函數(shù)中,我使用了三個(gè)為同步線(xiàn)程運(yùn)行的線(xiàn)程,而且在其中每個(gè)線(xiàn)程中都有一個(gè)可共享的資源。
這些線(xiàn)程以向第一個(gè)對(duì)象獲取封鎖這種方式運(yùn)行。但是當(dāng)它試著像第二個(gè)對(duì)象獲取封鎖時(shí),它就會(huì)進(jìn)入等待狀態(tài),因?yàn)樗呀?jīng)被另一個(gè)線(xiàn)程封鎖住了。這樣,在線(xiàn)程引起死鎖的過(guò)程中,就形成了一個(gè)依賴(lài)于資源的循環(huán)。
當(dāng)我執(zhí)行上面的程序時(shí),就產(chǎn)生了輸出,但是程序卻因?yàn)樗梨i無(wú)法停止。
t1 acquiring lock on java.lang.Object@6d9dd520
t1 acquired lock on java.lang.Object@6d9dd520
t2 acquiring lock on java.lang.Object@22aed3a5
t2 acquired lock on java.lang.Object@22aed3a5
t3 acquiring lock on java.lang.Object@218c2661
t3 acquired lock on java.lang.Object@218c2661
t1 acquiring lock on java.lang.Object@22aed3a5
t2 acquiring lock on java.lang.Object@218c2661
t3 acquiring lock on java.lang.Object@6d9dd520
在此我們可以清楚地在輸出結(jié)果中辨認(rèn)出死鎖局面,但是在我們實(shí)際生活所用的應(yīng)用中,發(fā)現(xiàn)死鎖并將它排除是非常難的。
分析死鎖
為了分析一個(gè)死鎖,我們需要關(guān)注下應(yīng)用中的Java線(xiàn)程轉(zhuǎn)存,在上一節(jié)中我已經(jīng)解釋了如何使用VisualVM收集資料或者jstack應(yīng)用程序產(chǎn)生線(xiàn)程轉(zhuǎn)存。
以下就是上述程序的線(xiàn)程轉(zhuǎn)存。
2012-12-27 19:08:34
Full thread dump Java HotSpot(TM) 64-Bit Server VM (23.5-b02 mixed mode):
"Attach Listener" daemon prio=5 tid=0x00007fb0a2814000 nid=0x4007 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"DestroyJavaVM" prio=5 tid=0x00007fb0a2801000 nid=0x1703 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"t3" prio=5 tid=0x00007fb0a204b000 nid=0x4d07 waiting for monitor entry [0x000000015d971000]
java.lang.Thread.State: BLOCKED (on object monitor)
at com.journaldev.threads.SyncThread.run(ThreadDeadlock.java:41)
- waiting to lock <0x000000013df2f658> (a java.lang.Object)
- locked <0x000000013df2f678> (a java.lang.Object)
at java.lang.Thread.run(Thread.java:722)
"t2" prio=5 tid=0x00007fb0a1073000 nid=0x4207 waiting for monitor entry [0x000000015d209000]
java.lang.Thread.State: BLOCKED (on object monitor)
at com.journaldev.threads.SyncThread.run(ThreadDeadlock.java:41)
- waiting to lock <0x000000013df2f678> (a java.lang.Object)
- locked <0x000000013df2f668> (a java.lang.Object)
at java.lang.Thread.run(Thread.java:722)
"t1" prio=5 tid=0x00007fb0a1072000 nid=0x5503 waiting for monitor entry [0x000000015d86e000]
java.lang.Thread.State: BLOCKED (on object monitor)
at com.journaldev.threads.SyncThread.run(ThreadDeadlock.java:41)
- waiting to lock <0x000000013df2f668> (a java.lang.Object)
- locked <0x000000013df2f658> (a java.lang.Object)
at java.lang.Thread.run(Thread.java:722)
"Service Thread" daemon prio=5 tid=0x00007fb0a1038000 nid=0x5303 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C2 CompilerThread1" daemon prio=5 tid=0x00007fb0a1037000 nid=0x5203 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C2 CompilerThread0" daemon prio=5 tid=0x00007fb0a1016000 nid=0x5103 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Signal Dispatcher" daemon prio=5 tid=0x00007fb0a4003000 nid=0x5003 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Finalizer" daemon prio=5 tid=0x00007fb0a4800000 nid=0x3f03 in Object.wait() [0x000000015d0c0000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x000000013de75798> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:135)
- locked <0x000000013de75798> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:151)
at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:177)
"Reference Handler" daemon prio=5 tid=0x00007fb0a4002000 nid=0x3e03 in Object.wait() [0x000000015cfbd000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x000000013de75320> (a java.lang.ref.Reference$Lock)
at java.lang.Object.wait(Object.java:503)
at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:133)
- locked <0x000000013de75320> (a java.lang.ref.Reference$Lock)
"VM Thread" prio=5 tid=0x00007fb0a2049800 nid=0x3d03 runnable
"GC task thread#0 (ParallelGC)" prio=5 tid=0x00007fb0a300d800 nid=0x3503 runnable
"GC task thread#1 (ParallelGC)" prio=5 tid=0x00007fb0a2001800 nid=0x3603 runnable
"GC task thread#2 (ParallelGC)" prio=5 tid=0x00007fb0a2003800 nid=0x3703 runnable
"GC task thread#3 (ParallelGC)" prio=5 tid=0x00007fb0a2004000 nid=0x3803 runnable
"GC task thread#4 (ParallelGC)" prio=5 tid=0x00007fb0a2005000 nid=0x3903 runnable
"GC task thread#5 (ParallelGC)" prio=5 tid=0x00007fb0a2005800 nid=0x3a03 runnable
"GC task thread#6 (ParallelGC)" prio=5 tid=0x00007fb0a2006000 nid=0x3b03 runnable
"GC task thread#7 (ParallelGC)" prio=5 tid=0x00007fb0a2006800 nid=0x3c03 runnable
"VM Periodic Task Thread" prio=5 tid=0x00007fb0a1015000 nid=0x5403 waiting on condition
JNI global references: 114
Found one Java-level deadlock:
=============================
"t3":
waiting to lock monitor 0x00007fb0a1074b08 (object 0x000000013df2f658, a java.lang.Object),
which is held by "t1"
"t1":
waiting to lock monitor 0x00007fb0a1010f08 (object 0x000000013df2f668, a java.lang.Object),
which is held by "t2"
"t2":
waiting to lock monitor 0x00007fb0a1012360 (object 0x000000013df2f678, a java.lang.Object),
which is held by "t3"
Java stack information for the threads listed above:
===================================================
"t3":
at com.journaldev.threads.SyncThread.run(ThreadDeadlock.java:41)
- waiting to lock <0x000000013df2f658> (a java.lang.Object)
- locked <0x000000013df2f678> (a java.lang.Object)
at java.lang.Thread.run(Thread.java:722)
"t1":
at com.journaldev.threads.SyncThread.run(ThreadDeadlock.java:41)
- waiting to lock <0x000000013df2f668> (a java.lang.Object)
- locked <0x000000013df2f658> (a java.lang.Object)
at java.lang.Thread.run(Thread.java:722)
"t2":
at com.journaldev.threads.SyncThread.run(ThreadDeadlock.java:41)
- waiting to lock <0x000000013df2f678> (a java.lang.Object)
- locked <0x000000013df2f668> (a java.lang.Object)
at java.lang.Thread.run(Thread.java:722)
Found 1 deadlock.
這三個(gè)線(xiàn)程轉(zhuǎn)存的輸出清楚地說(shuō)明了死鎖環(huán)境和線(xiàn)程,以及包含死鎖環(huán)境的資源。
為了分析死鎖,我們需要關(guān)注死鎖狀態(tài)的線(xiàn)程,然后資源再等待去封鎖,每一個(gè)資源都有一個(gè)獨(dú)特的ID,有了這個(gè)ID我們就能發(fā)現(xiàn)是哪一個(gè)進(jìn)程已經(jīng)封鎖住對(duì)象。舉個(gè)例子,線(xiàn)程“t3”正在等待封鎖0x000000013df2f658,但是它已經(jīng)被線(xiàn)程“t1”封鎖住了。
當(dāng)我們分析死鎖環(huán)境的時(shí)候,如果發(fā)現(xiàn)線(xiàn)程正在引起死鎖,這是我們就要改變代碼來(lái)避免死鎖的產(chǎn)生。
避免死鎖
有很多方針可供我們使用來(lái)避免死鎖的局面。
避免嵌套封鎖:這是死鎖最主要的原因的,如果你已經(jīng)有一個(gè)資源了就要避免封鎖另一個(gè)資源。如果你運(yùn)行時(shí)只有一個(gè)對(duì)象封鎖,那是幾乎不可能出現(xiàn)一個(gè)死鎖局面的。例如,這里是另一個(gè)運(yùn)行中沒(méi)有嵌套封鎖的run()方法,而且程序運(yùn)行沒(méi)有死鎖局面,運(yùn)行得很成功。
public void run() {
String name = Thread.currentThread().getName();
System.out.println(name + " acquiring lock on " + obj1);
synchronized (obj1) {
System.out.println(name + " acquired lock on " + obj1);
work();
}
System.out.println(name + " released lock on " + obj1);
System.out.println(name + " acquiring lock on " + obj2);
synchronized (obj2) {
System.out.println(name + " acquired lock on " + obj2);
work();
}
System.out.println(name + " released lock on " + obj2);
System.out.println(name + " finished execution.");
}
只對(duì)有請(qǐng)求的進(jìn)行封鎖:你應(yīng)當(dāng)只想你要運(yùn)行的資源獲取封鎖,比如在上述程序中我在封鎖的完全的對(duì)象資源。但是如果我們只對(duì)它所屬領(lǐng)域中的一個(gè)感興趣,那我們應(yīng)當(dāng)封鎖住那個(gè)特殊的領(lǐng)域而并非完全的對(duì)象。
避免無(wú)限期的等待:如果兩個(gè)線(xiàn)程正在等待對(duì)象結(jié)束,無(wú)限期的使用線(xiàn)程加入,如果你的線(xiàn)程必須要等待另一個(gè)線(xiàn)程的結(jié)束,若是等待進(jìn)程的結(jié)束加入最好準(zhǔn)備最長(zhǎng)時(shí)間。
看完本文有收獲?請(qǐng)轉(zhuǎn)發(fā)分享給更多人
關(guān)注「ImportNew」,提升Java技能
《單片機(jī)C51項(xiàng)目設(shè)計(jì)與開(kāi)發(fā)》以實(shí)用案例為導(dǎo)向,通過(guò)19個(gè)典型任務(wù),基于工作過(guò)程的學(xué)習(xí)思路,主要介紹單片機(jī)開(kāi)發(fā)工具軟件(Keil、Proteus)、C51程序設(shè)計(jì)、廣告燈、電子鐘、LED屏、數(shù)字電壓表、萬(wàn)年歷以及單片機(jī)綜合應(yīng)用系統(tǒng)設(shè)計(jì)(機(jī)器人)等內(nèi)容?!秵纹瑱C(jī)C51項(xiàng)目設(shè)計(jì)與開(kāi)發(fā)》注重技能訓(xùn)練,內(nèi)容貼近電子行業(yè)的職業(yè)崗位需求,適當(dāng)增加一些當(dāng)今流行的新器件和新技術(shù),并提供了詳細(xì)的原理說(shuō)明、電路圖、完整的程序代碼及程序流程圖,具有很強(qiáng)的實(shí)用性、可讀性和可操作性。
《單片機(jī)C51項(xiàng)目設(shè)計(jì)與開(kāi)發(fā)》可用作高等院校的電子信息類(lèi)、通信類(lèi)、自動(dòng)化類(lèi)、機(jī)電類(lèi)等專(zhuān)業(yè)單片機(jī)技術(shù)課程的教材,也可用作應(yīng)用型本科院校和培訓(xùn)班的教材以及電子產(chǎn)品設(shè)計(jì)人員的參考書(shū)。