【摘要】多線程技術能夠使應用程序并行執行,提高CPU利用率,容易實現網絡上的實時交互行為。本文分析了java的多線程機制,介紹了在網絡上傳文件中運用java多線程機制實現對圖片上傳的加速。
【關鍵詞】java多線程;Servlet;圖片上傳
1.java的多線程機制
首先多線程是相對于單線程而言的,指的是在一個程序中可以定義多個線程并同時運行它們,每個線程可以執行不同的任務。與進程不同的是,同類多線程共享一塊內存空間和一組系統資源,所以,系統創建多線程花費單價較小。因此,也稱線程為輕負荷進程。
很多計算機編程語言需要外部軟件包來實現多線程,而java語言則內在支持多線程,所有的類都是在多線程思想下定義的,使用java的多線程機制編程可將程序的任務分解為幾個并行的子任務,通過縣城的并發執行來加速程序運行,提高CPU的利用率[1]。例如:在網絡編程中,有很多功能可以并發執行。網絡傳輸速度一般較慢,用戶輸入速度也較慢,因此可以設計兩個獨立線程分別完成這兩個任務而不影響正常的顯示或其他功能。
2.多線程的圖片上傳技術
由于用戶上傳圖片時是把批量的圖片數據傳到主服務,然后由主服務器連接文件上傳服務器的Servlet,把圖片數據傳遞給該Servlet,由它調用圖片壓縮方法,壓縮、寫入圖片。由于壓縮和I/O操作都是比較占用時間的操作,如果采用串行的方式必然影響系統的響應速度,而采用多線程技術,使所有圖片的壓縮和I/O并發進行就可以大大提升系統的響應時間。
考慮到Servlet是以多線程方式運行的,故而只需要在主服務端也以多線性方式把單張圖片的請求發送給文件服務器的Servlet即可,然后等待所有線程執行完,把執行結果回調,即可通過判斷對調的結果就可以判斷每張圖片的上傳操作是否成功,以此為標準決定往數據庫寫入哪些數據。
具體的實現方式如下:
首先,創建創建線程池,池中的線程數一般由系統核心數決定。
privatestaticExecutorServiceimageService=Executors.newFixedThreadPool(3);
然后,創建一個任務隊列,其中每張圖片的一次上傳都是隊列中的一個任務。
List
for(UploadFile file:files){
callableList.add(new UploadRequest Sender(url,file));
}
最后,等待所有上傳結果(返回碼)出來后,根據圖結果決定數據庫的操作。
try{
List
invokeAll(callableList);
for(int i=0;i if(futures.get(i).get()==200){ photos.add(addPhoto(album,uploadDomain+photoBasePath +files.get(i).getShortPath())); } } }catch(InterruptedException e){ e.printStackTrace(); }catch(ExecutionException e){ e.printStackTrace(); } 另外,由于每個任務的執行都需要返回結果,故而需要一個實現了Callable接口的線程類來組成這個任務隊列[2],而在此,通過UploadRequestSender這個類來發送單張圖片上傳請求,并把操作結果返回。具體實現如下: public class UploadRequestSender implements Callable private URL servletUrl; private UploadFile file; public UploadRequestSender(URL servletUrl,UploadFile file){ this.servletUrl=servletUrl; this.file=file; } private int sendImageToServlet()throws IOException{ HttpURLConnection connection= (HttpURLConnection)servletUrl.openConnection(); connection.setDoOutput(true); connection.setDoInput(true); //發送格式為二進制流 connection.setRequestProperty (\"Content-Type\",\"application/octet-stream\"); connection.setRequestMethod(\"POST\"); connection.setRequestProperty(\"shortPath\",file.getShortPath()); OutputStream os=connection.getOutput Stream(); os.write(file.getFileData()); System.out.println(connection.get ContentType()+\":\" +connection.getResponseCode()); os.close(); return connection.getResponseCode(); } public Integer call()throws Exception{ return sendImageToServlet(); } } 3.總結 其中,call()方法即線程所要執行的操作,而返回值即操作執行的結果,也即前面futures中與該應任務相應的節點值。 而在上傳服務器端,由于Servlet對于每個請求都會通過一個線程來響應該請求,故而也會以多線程的方式來壓縮和進行圖片的I/O,因此便通過多線程技術實現了對圖片上傳的加速。 參考文獻 [1]邵麗萍.JAVA語言程序設計[M].清華大學出版社, 2008:8. [2][美]Brian Goetz,Tim Peierls,Joshua Bloch,Joseph Bowbeer,David Holmes,Goug Lee,韓鍇,方妙.Java并發編程實踐(Java Concurrency In Practice)[M].北京:電子工業出版社,2007. [3]萬志堅.用于圖像處理的Java Applet研究[J].湖北工業大學學報,2006,6(21)3. 作者簡介:劉丹(1978—),女,吉林長春人,大連廣播電視大學講師,研究方向:軟件技術與理論。