999精品在线视频,手机成人午夜在线视频,久久不卡国产精品无码,中日无码在线观看,成人av手机在线观看,日韩精品亚洲一区中文字幕,亚洲av无码人妻,四虎国产在线观看 ?

多線程技術及其在Java ME中的應用研究

2008-12-31 00:00:00徐金寶
電腦知識與技術 2008年35期

摘要:多線程技術是提高程序并發性和效率的重要手段,在網絡應用、數據庫應用軟件、因特網以及嵌入式系統的開發中得到廣泛的應用。深入分析多線程及其同步機制、死鎖問題,并將多線程技術運用到Java ME開發中的圖像平滑移動、低層界面設計、無線消息接收、競技游戲、移動電子商務開發實踐中,并分析開發中會出現的死鎖問題,對開發高效率的Java ME應用程序具有重要意義。

關鍵詞:線程;同步;死鎖;Java ME

中圖分類號:TP316文獻標識碼:A文章編號:1009-3044(2008)35-2525-03

Research on Multithreading technology and its applications in Java ME

XU Jin-bao

(College of Computer Engineering, Nanjing Institute of Technology, Nanjing 211167, China)

Abstract: Multi-thread technology is the important means to improve the efficiency and concurrency of software system,widely used in the network applications, database applications, Internet and the the embedded systems. By deeply analynizing on multi-thread and its synchronization mechanisms, deadlock problems, multi-thread technology is discussed in the development of the image smoothing mobile, low-level interface design, wireless messages reception, fighting games, mobile e-commerce in Java ME, and a solution on the deadlock issues is provided. Multi-thread is of great significance to the development of highly efficient Java ME applications.

Key words: thread; synchronized; deadlock; Java ME

1 引言

多線程技術在網絡應用、數據庫應用軟件、因特網以及嵌入式系統的開發中得到廣泛的應用。多線程是提高系統效率、提高軟件并發性的重要方式。傳統的多進程、多線程理論對指導多線程編程有很大幫助,但跟實際應用結合的不夠。在開發實踐中,由于采用了多線程技術,就會帶來一些與應用有關的問題,對這些問題處理的不好,可能會發生錯誤,或發生死鎖,或系統效率得不到應有的提高。因此,對Java中多線程程序設計進行深入分析,并與Java ME開發結合起來,開發出效率高、運行穩定的手機應用軟件。

2 多線程概念

傳統操作系統的進程定義是:進程是程序在某個數據集上的一次執行,是資源分配與保護的單位,也是執行的單位。為了提高程序并發執行時的時空開銷,使得并發粒度更小,并發性更好,現代操作系統就將進程的資源分配與保護功能和執行功能分開,執行功能由線程完成,進程仍然作為資源的分配與保護單位,無需頻繁切換。線程共享進程地址空間,線程間通信簡單。

線程具有運行、就緒和等待態。當多個線程對共享資源(臨界資源)進行存取時,如果不采取有效的機制,會發生與時間有關的錯誤。對共享資源進行訪問的線程中的代碼段稱為臨界區(Critical Section),多個線程訪問臨界資源時,臨界區管理必須滿足三個條件:互斥使用,有空讓進;忙則等待,有限等待;擇一而入,算法可行。這是線程互斥的例子。線程還有同步的關系。當多個線程協作完成任務,如生產者/消費者問題,這就是線程的同步。互斥是線程的競爭關系,同步是線程的協作關系。互斥可以看作是一種特殊的同步。

此外,線程不斷推進,會出現這樣的一種狀態:在一個線程集合中,所有的線程都處于等待態,等待的事件只能由此集合中的其他線程才能引發,這種局面就是死鎖。

在軟件開發實踐中,對于多線程程序設計,要精益求精,慎之又慎,要妥善處理進程的同步與互斥關系,同時要避免死鎖的發生。

3 Java中多線程的實現

3.1 Java多線程的兩種實現方式

Java中的定時器就是一種多線程技術。首先需要定義一個繼承自類TimerTask的類,然后建立一個Timer對象,將TimerTask類的對象加入到Timer的schedule()方法中即可,schedule()方法的第二個參數是定時時間間隔,真正需要并發執行的代碼放在TimerTask的run()方法中。

在Java中有兩種建立多線程程序的方法。一種是繼承Thread類,一種是實現Runnable 接口。繼承Thread類的方法簡單,實現Runnable接口的方法更通用。需要并發執行的代碼,兩種方法都與定時器一樣,都是在run()方法中予以實現。建立線程的兩種方法如下:

classMyThread1 extends Thread{//繼承Thread類的方式

public void run();

}

classMyThread2 implementss Runnable{//實現Runnable接口的方式

public void run();

}

在使用時,第一種方式在主方法里可以用new MyThread1().start();進行;第二種方式則稍微復雜一點:new Thread(new MyThread2()).start();。

3.2 Java中對線程同步與互斥的解決

在操作系統理論中,軟件大師Dijkstra運用PV操作和信號量對進程的互斥和同步進行了有效的解決,該思想已經廣泛應用到Java程序設計中。

在Java 中,解決線程的同步與互斥問題,可以通過Object中的三個方法:wait()、notify()和notifyAll(),加上關鍵字synchronized來解決。synchronized關鍵字有兩種用法,一種是修飾對象中的方法,這樣,該方法只能順序執行,不可并發,從而保證線程之間的互斥;但是當方法代碼不是自己寫的或不能看到源代碼,可以通過synchronized關鍵字來修飾該對象本身,這是可行的,但缺點是該對象中的所有的方法都被串行化了,雖然有些方法還是可以并發執行的,某種程度上降低了一些并發效率。

生產者/消費者問題是典型的線程同步與互斥問題。解決方法是:建立一個緩沖區類Box,有一整型屬性value和一布爾變量available,該類有兩個方法存put()和取get(),均為synchronized方法。當取數時,先檢測available,若為1,則調用wait()進入等待態;若為true就直接取數,將available置為1,同時還需要調用notify()喚醒等待線程;當存數時,先檢測available,若為true,則調用wait(),若為1,則存數,將available置為true,調用notify()喚醒等待線程。

緩沖區Box類設計好之后,就可以設計生產者Producer和消費者Consumer類。這兩個類相對就簡單了,這兩個類都是線程類,有兩個屬性,一個是String類型的name,用來標識線程名詞,另一個就是緩沖區Box類型的box,在run()方法中就可以通過Box的get()或put()方法進行生產或消費數據了。

此外,Java中還有一個線程局部變量ThreadLocal。如果把synchronized看著同步鎖,是一種“以時間換空間”的策略,則ThreadLocal為每個獨立的線程提供一個變量的副本,每個線程獨立使用,每個線程修改線程變量時,實際上修改的是變量的副本,不會影響到其他線程,運用ThreadLocal實現線程的同步是一種“以空間換時間”的策略。

3.3 Java中對線程死鎖的解決

破壞產生死鎖的四個必要條件之一就能防止死鎖,運用銀行家算法能避免死鎖,但這兩種方法,前者條件太強,后者需要的系統開銷太大,因此,在Java應用開發中都不現實。對死鎖問題的解決主要是通過認真分析wait()方法調用的順序,wait()方法調用順序的不當,是產生死鎖的主要原因。但值得注意的是,wait()調用次序的改變可能會降低程序運行的速度。由于死鎖是小概率事件,有時寧可放松對死鎖的監管,而讓系統運行得更快。

3.4 Java中多線程設計的注意點

隨著Java的發展,一些線程的方法已經過時(deprecated)。判斷一個進程是否結束的iaAlive()已經不建議使用。判斷線程是否結束可以通過建立一個線程狀態的標志變量進行,等待其他線程結束可以使用join()方法。

此外,Thread中的stop()、suspend()和resume()方法,在實際編程中最好不要使用,這些方法可能會導致系統崩潰。

4 多線程在Java ME中的應用

4.1 多線程在圖像平滑移動中的應用

在Java ME開發中,特別是在使用低層界面API時,經常需要在屏幕上移動一個物體或圖像,并且移動到下一位置時需要進行復雜的坐標運算,如果把坐標計算與圖像顯示放在同一個線程中,則會出現圖像顯示慢,從而圖像移動不平滑的現象。解決此問題,一般的方法是通過設計兩個線程,一個線程專門負責圖像顯示,另一個線程專門負責坐標的計算,這兩個線程的關系應該是制約的(同步的),在圖像顯示時,是不能改變坐標的。在Java ME環境下,對這兩個線程的協調主要有兩種解決辦法。

4.1.1 應用關鍵字synchronized實現線程同步

計算坐標的工作可以設計成一個線程,為了簡單起見,可以通過定時器來實現該線程。設計算坐標的方法為CalculateXY(),該方法必須是synchronized方法,將該方法調用放到TimerTask對象的run()方法中去,在調用了CalculateXY()方法計算出新的坐標后,需要調用repaint()方法進行屏幕重畫。然后將該TimerTask對象作為new Timer()的第一個參數,第二參數和第三參數則可以設定為以毫秒計的定時間隔。

對于Canvas類中的paint()方法,在繪制圖像時需要調用CalculateXY()方法計算出的坐標時,需要在執行過程中鎖定Canvas對象,這樣可以使別的方法不能存取Canvas對象中的圖像對象,從而實現線程間的同步,主要代碼如下:

protected void paint(Graphics g){

//一些背景設置

synchronized(this){

//圖像顯示

}

}

4.1.2 應用Display的callSerially方法實現線程同步

Display類中callSerially()方法是一個事件序列化的方法,它的作用是使指定的線程對象首先暫停,讓系統首先完成屏幕的顯示,等屏幕顯示完畢以后再使線程繼續執行。callSerially()方法只有一個類型為Runnable的參數,使用callSerially()方法引發的run()方法要在所有未處理的repaint請求都得到滿足之后才被調用,如果將坐標計算方法CalculateXY()放入run()方法,則方法CalculateXY()就會與方法paint()串行執行,從而達到圖像繪制與坐標計算的同步。具體實現方法如下:

Thread myThread=new Thread{//創建線程myThread

public void run(){

if(isRunning){//若線程未結束則運行,isRunning是線程結束標志變量

CalculateXY();//坐標計算

repaint();//屏幕重繪

serviceRepaints();//讓paint()方法盡快執行

}

try{

Thread.sleep(50);

}

catch(Exception e){}

}

display.callSerially(this);//將線程myMyThread的run()方法加入到事件 //隊列中,要求再次執行myThread的run()方法

};

myThread.start();//啟動線程myThread,運行run()

//當paint()方法結束后,會再次啟動run()方法運行,然后繼續進行坐標計算,重繪。

4.2 多線程在競技游戲中的應用

競技游戲是Java ME的一項重要應用。競技游戲設計中,需要使用LayerMananger對圖層Layer進行管理,并且靈活使用觀察窗口(ViewWindow)。背景采用TiledLayer,角色采用Sprite。競技游戲需要很快地響應游戲用戶的按鍵。一種有效的做法是:將獲得按鍵以及按鍵的處理以及設定觀察窗口放在一個線程中實現,這樣就可以快速響應游戲用戶的按鍵。

4.3 多線程在移動電子商務中的應用

移動電子商務需要有服務器,服務器必須能夠同時處理多個客戶的請求。服務端的軟件設計必須是多線程的,可以采用線程池來進行。在高性能的服務器軟件設計中,線程池的管理顯得尤為重要,是影響性能的一個重要因素。

4.4 多線程在無線消息傳遞中的應用

在無線消息傳遞中,接收方為了接收信息,需要始終啟動接收程序,在實際應用中,都是通過注冊一個MessageListener接口來監聽短消息的到來。為了能夠及時處理新到達的短消息,對新消息的讀取采用一個新的線程。更進一步,考慮到手機內存容量有限,CPU速度較慢的情況下,甚至還可以采用PushRegistry技術來更進一步提高效率,即由AMS(應用程序管理系統)監測短消息的到來,到有消息到來時,啟動相應程序進行消息讀取處理。

4.5 多線程在界面設計時會出現死鎖的情況

與swing不同,MIDP中的所有界面控件都是線程安全的。 用戶使用界面控件,在內部都是通過回調(callback)函數,而這些回調函數都進行了序列化,均是順序執行的。但是,在低級界面設計中,假如在Canvas的serviceRepaints()方法中鎖定了paint()方法將要訪問的對象,就會發生死鎖。這是因為serviceRepaints()是等待paint()方法立即執行,而paint()方法所訪問的對象卻被鎖定了,這樣兩個方法都不能完成,從而互相等待。因此,在serviceRepaints()方法中不能鎖定paint()方法將要訪問的對象。

5 結束語

以上對多線程技術及其在Java ME中的應用進行了分析,但多線程技術決不僅僅應用在以上這些方面。隨著Java技術的發展,Java的多線程技術也在不斷發展與成熟,在Java ME中的應用將會更加深入。對Java多線程的深入掌握和應用,將會開發出更加優秀的移動軟件系統。

參考文獻:

[1] 孫鐘秀.操作系統[M].北京:高等教育出版社,2008:164-217.

[2] 詹建飛.J2ME開發精解[M].北京:電子工業出版社,2006:155-171.

[3] 莊東.JBuilderX無線應用開發[M].北京:電子工業出版社,2004:160-171.

[4] 孔明放.J2ME程序設計教程[M].北京:科學出版社,2005:142-147.

[5] 池雅慶,周珺.J2ME手機應用項目開發實踐[M].北京:中國鐵道出版社,2007:130-145.

主站蜘蛛池模板: 亚洲一区二区在线无码| 九九久久精品免费观看| 亚洲高清国产拍精品26u| 91精品啪在线观看国产91九色| 日韩美毛片| 欧美激情,国产精品| 黄网站欧美内射| 国产精品视频观看裸模 | 成人国产免费| 久久精品嫩草研究院| 手机在线国产精品| 亚洲日韩国产精品无码专区| 亚洲欧美人成电影在线观看| 欧美精品成人| 欧美一区精品| 在线精品视频成人网| 亚洲国产亚综合在线区| 亚洲免费毛片| 亚洲欧美日韩成人高清在线一区| 国产精品天干天干在线观看| 国产激情无码一区二区免费| 欧美黄色网站在线看| 国产99视频精品免费视频7| 亚洲精品无码久久久久苍井空| 亚洲第一国产综合| 国产免费羞羞视频| 无码中文字幕乱码免费2| 色香蕉网站| 国产女主播一区| 婷婷午夜影院| 久久综合婷婷| 亚洲乱码在线视频| 丁香婷婷激情综合激情| 少妇精品网站| 亚洲日韩精品欧美中文字幕| 色偷偷一区| 亚洲精品综合一二三区在线| 久草视频精品| 亚洲精选无码久久久| 97成人在线观看| 色135综合网| 国产本道久久一区二区三区| 亚洲另类国产欧美一区二区| 精品国产免费人成在线观看| 国产一区二区网站| 伊人91视频| 欧美a在线视频| 人与鲁专区| 久久久久久午夜精品| 免费国产无遮挡又黄又爽| 成人综合在线观看| 天天色天天操综合网| 国产亚洲精品资源在线26u| 国产极品美女在线| 亚洲动漫h| 免费看的一级毛片| 亚洲国产精品久久久久秋霞影院| 欧美午夜久久| 成人一级免费视频| 刘亦菲一区二区在线观看| 91精选国产大片| 国产SUV精品一区二区| 免费99精品国产自在现线| 在线另类稀缺国产呦| 香蕉久人久人青草青草| 国产精品yjizz视频网一二区| 高潮爽到爆的喷水女主播视频| 日本国产在线| 中文一级毛片| 精品无码人妻一区二区| 免费高清自慰一区二区三区| 色天天综合久久久久综合片| 久久久久免费精品国产| 欧美在线综合视频| 国产欧美视频在线观看| 丰满人妻一区二区三区视频| 青草视频免费在线观看| 亚洲免费福利视频| 日韩成人在线一区二区| 尤物视频一区| 毛片免费在线| 国模极品一区二区三区|