package?socket;

成都創(chuàng)新互聯(lián)公司專業(yè)為企業(yè)提供中陽(yáng)網(wǎng)站建設(shè)、中陽(yáng)做網(wǎng)站、中陽(yáng)網(wǎng)站設(shè)計(jì)、中陽(yáng)網(wǎng)站制作等企業(yè)網(wǎng)站建設(shè)、網(wǎng)頁(yè)設(shè)計(jì)與制作、中陽(yáng)企業(yè)網(wǎng)站模板建站服務(wù),10多年中陽(yáng)做網(wǎng)站經(jīng)驗(yàn),不只是建網(wǎng)站,更提供有價(jià)值的思路和整體網(wǎng)絡(luò)服務(wù)。
import?java.io.BufferedReader;
import?java.io.IOException;
import?java.io.InputStreamReader;
import?java.io.PrintWriter;
import?java.net.ServerSocket;
import?java.net.Socket;
public?class?SocketService?{
//搭建服務(wù)器端
public?static?void?main(String[]?args)?throws?IOException{
SocketService?socketService?=?new?SocketService();
//1、a)創(chuàng)建一個(gè)服務(wù)器端Socket,即SocketService?
socketService.oneServer();
}
public??void?oneServer(){
try{
ServerSocket?server=null;
try{
server=new?ServerSocket(5209);
//b)指定綁定的端口,并監(jiān)聽(tīng)此端口。
System.out.println("服務(wù)器啟動(dòng)成功");
//創(chuàng)建一個(gè)ServerSocket在端口5209監(jiān)聽(tīng)客戶請(qǐng)求
}catch(Exception?e)?{
System.out.println("沒(méi)有啟動(dòng)監(jiān)聽(tīng):"+e);
//出錯(cuò),打印出錯(cuò)信息
}
Socket?socket=null;
try{
socket=server.accept();
//2、調(diào)用accept()方法開(kāi)始監(jiān)聽(tīng),等待客戶端的連接?
//使用accept()阻塞等待客戶請(qǐng)求,有客戶
//請(qǐng)求到來(lái)則產(chǎn)生一個(gè)Socket對(duì)象,并繼續(xù)執(zhí)行
}catch(Exception?e)?{
System.out.println("Error."+e);
//出錯(cuò),打印出錯(cuò)信息
}
//3、獲取輸入流,并讀取客戶端信息?
String?line;
BufferedReader?in=new?BufferedReader(new?InputStreamReader(socket.getInputStream()));
//由Socket對(duì)象得到輸入流,并構(gòu)造相應(yīng)的BufferedReader對(duì)象
PrintWriter?writer=new?PrintWriter(socket.getOutputStream());
//由Socket對(duì)象得到輸出流,并構(gòu)造PrintWriter對(duì)象
BufferedReader?br=new?BufferedReader(new?InputStreamReader(System.in));
//由系統(tǒng)標(biāo)準(zhǔn)輸入設(shè)備構(gòu)造BufferedReader對(duì)象
System.out.println("Client:"+in.readLine());
//在標(biāo)準(zhǔn)輸出上打印從客戶端讀入的字符串
line=br.readLine();
//從標(biāo)準(zhǔn)輸入讀入一字符串
//4、獲取輸出流,響應(yīng)客戶端的請(qǐng)求?
while(!line.equals("end")){
//如果該字符串為?"bye",則停止循環(huán)
writer.println(line);
//向客戶端輸出該字符串
writer.flush();
//刷新輸出流,使Client馬上收到該字符串
System.out.println("Server:"+line);
//在系統(tǒng)標(biāo)準(zhǔn)輸出上打印讀入的字符串
System.out.println("Client:"+in.readLine());
//從Client讀入一字符串,并打印到標(biāo)準(zhǔn)輸出上
line=br.readLine();
//從系統(tǒng)標(biāo)準(zhǔn)輸入讀入一字符串
}?//繼續(xù)循環(huán)
//5、關(guān)閉資源?
writer.close();?//關(guān)閉Socket輸出流
in.close();?//關(guān)閉Socket輸入流
socket.close();?//關(guān)閉Socket
server.close();?//關(guān)閉ServerSocket
}catch(Exception?e)?{//出錯(cuò),打印出錯(cuò)信息
System.out.println("Error."+e);
}
}
}
soapenv:Header/
soapenv:Body
api:getEmp
shopIdstring/shopId
/api:getEmp
/soapenv:Body
/soapenv:Envelope
這個(gè)時(shí)SOAP協(xié)議的標(biāo)準(zhǔn)報(bào)文格式,客戶端只要發(fā)送這樣的報(bào)文給支持SOAP協(xié)議的webservice服務(wù)器即可成功調(diào)用web service服務(wù)
服務(wù)端:部署服務(wù)只需要自己定義服務(wù)的接口和實(shí)現(xiàn)類,并用@webservice注解,通過(guò)endPoint類直接發(fā)布即可
15.3 服務(wù)多個(gè)客戶
JabberServer可以正常工作,但每次只能為一個(gè)客戶程序提供服務(wù)。在典型的服務(wù)器中,我們希望同時(shí)能處理多個(gè)客戶的請(qǐng)求。解決這個(gè)問(wèn)題的關(guān)鍵就是多線程處理機(jī)制。而對(duì)于那些本身不支持多線程的語(yǔ)言,達(dá)到這個(gè)要求無(wú)疑是異常困難的。通過(guò)第14章的學(xué)習(xí),大家已經(jīng)知道Java已對(duì)多線程的處理進(jìn)行了盡可能的簡(jiǎn)化。由于Java的線程處理方式非常直接,所以讓服務(wù)器控制多名客戶并不是件難事。
最基本的方法是在服務(wù)器(程序)里創(chuàng)建單個(gè)ServerSocket,并調(diào)用accept()來(lái)等候一個(gè)新連接。一旦accept()返回,我們就取得結(jié)果獲得的Socket,并用它新建一個(gè)線程,令其只為那個(gè)特定的客戶服務(wù)。然后再調(diào)用accept(),等候下一次新的連接請(qǐng)求。
對(duì)于下面這段服務(wù)器代碼,大家可發(fā)現(xiàn)它與JabberServer.java例子非常相似,只是為一個(gè)特定的客戶提供服務(wù)的所有操作都已移入一個(gè)獨(dú)立的線程類中:
//: MultiJabberServer.java
// A server that uses multithreading to handle
// any number of clients.
import java.io.*;
import java.net.*;
class ServeOneJabber extends Thread {
private Socket socket;
private BufferedReader in;
private PrintWriter out;
public ServeOneJabber(Socket s)
throws IOException {
socket = s;
in =
new BufferedReader(
new InputStreamReader(
socket.getInputStream()));
// Enable auto-flush:
out =
new PrintWriter(
new BufferedWriter(
new OutputStreamWriter(
socket.getOutputStream())), true);
// If any of the above calls throw an
// exception, the caller is responsible for
// closing the socket. Otherwise the thread
// will close it.
start(); // Calls run()
}
public void run() {
try {
while (true) {
String str = in.readLine();
if (str.equals("END")) break;
System.out.println("Echoing: " + str);
out.println(str);
}
System.out.println("closing...");
} catch (IOException e) {
} finally {
try {
socket.close();
} catch(IOException e) {}
}
}
}
public class MultiJabberServer {
static final int PORT = 8080;
public static void main(String[] args)
throws IOException {
ServerSocket s = new ServerSocket(PORT);
System.out.println("Server Started");
try {
while(true) {
// Blocks until a connection occurs:
Socket socket = s.accept();
try {
new ServeOneJabber(socket);
} catch(IOException e) {
// If it fails, close the socket,
// otherwise the thread will close it:
socket.close();
}
}
} finally {
s.close();
}
}
} ///:~
每次有新客戶請(qǐng)求建立一個(gè)連接時(shí),ServeOneJabber線程都會(huì)取得由accept()在main()中生成的Socket對(duì)象。然后和往常一樣,它創(chuàng)建一個(gè)BufferedReader,并用Socket自動(dòng)刷新PrintWriter對(duì)象。最后,它調(diào)用Thread的特殊方法start(),令其進(jìn)行線程的初始化,然后調(diào)用run()。這里采取的操作與前例是一樣的:從套掃字讀入某些東西,然后把它原樣反饋回去,直到遇到一個(gè)特殊的"END"結(jié)束標(biāo)志為止。
同樣地,套接字的清除必須進(jìn)行謹(jǐn)慎的設(shè)計(jì)。就目前這種情況來(lái)說(shuō),套接字是在ServeOneJabber外部創(chuàng)建的,所以清除工作可以“共享”。若ServeOneJabber構(gòu)建器失敗,那么只需向調(diào)用者“擲”出一個(gè)違例即可,然后由調(diào)用者負(fù)責(zé)線程的清除。但假如構(gòu)建器成功,那么必須由ServeOneJabber對(duì)象負(fù)責(zé)線程的清除,這是在它的run()里進(jìn)行的。
請(qǐng)注意MultiJabberServer有多么簡(jiǎn)單。和以前一樣,我們創(chuàng)建一個(gè)ServerSocket,并調(diào)用accept()允許一個(gè)新連接的建立。但這一次,accept()的返回值(一個(gè)套接字)將傳遞給用于ServeOneJabber的構(gòu)建器,由它創(chuàng)建一個(gè)新線程,并對(duì)那個(gè)連接進(jìn)行控制。連接中斷后,線程便可簡(jiǎn)單地消失。
如果ServerSocket創(chuàng)建失敗,則再一次通過(guò)main()擲出違例。如果成功,則位于外層的try-finally代碼塊可以擔(dān)保正確的清除。位于內(nèi)層的try-catch塊只負(fù)責(zé)防范ServeOneJabber構(gòu)建器的失敗;若構(gòu)建器成功,則ServeOneJabber線程會(huì)將對(duì)應(yīng)的套接字關(guān)掉。
為了證實(shí)服務(wù)器代碼確實(shí)能為多名客戶提供服務(wù),下面這個(gè)程序?qū)?chuàng)建許多客戶(使用線程),并同相同的服務(wù)器建立連接。每個(gè)線程的“存在時(shí)間”都是有限的。一旦到期,就留出空間以便創(chuàng)建一個(gè)新線程。允許創(chuàng)建的線程的最大數(shù)量是由final int maxthreads決定的。大家會(huì)注意到這個(gè)值非常關(guān)鍵,因?yàn)榧偃绨阉O(shè)得很大,線程便有可能耗盡資源,并產(chǎn)生不可預(yù)知的程序錯(cuò)誤。
//: MultiJabberClient.java
// Client that tests the MultiJabberServer
// by starting up multiple clients.
import java.net.*;
import java.io.*;
class JabberClientThread extends Thread {
private Socket socket;
private BufferedReader in;
private PrintWriter out;
private static int counter = 0;
private int id = counter++;
private static int threadcount = 0;
public static int threadCount() {
return threadcount;
}
public JabberClientThread(InetAddress addr) {
System.out.println("Making client " + id);
threadcount++;
try {
socket =
new Socket(addr, MultiJabberServer.PORT);
} catch(IOException e) {
// If the creation of the socket fails,
// nothing needs to be cleaned up.
}
try {
in =
new BufferedReader(
new InputStreamReader(
socket.getInputStream()));
// Enable auto-flush:
out =
new PrintWriter(
new BufferedWriter(
new OutputStreamWriter(
socket.getOutputStream())), true);
start();
} catch(IOException e) {
// The socket should be closed on any
// failures other than the socket
// constructor:
try {
socket.close();
} catch(IOException e2) {}
}
// Otherwise the socket will be closed by
// the run() method of the thread.
}
public void run() {
try {
for(int i = 0; i 25; i++) {
out.println("Client " + id + ": " + i);
String str = in.readLine();
System.out.println(str);
}
out.println("END");
} catch(IOException e) {
} finally {
// Always close it:
try {
socket.close();
} catch(IOException e) {}
threadcount--; // Ending this thread
}
}
}
public class MultiJabberClient {
static final int MAX_THREADS = 40;
public static void main(String[] args)
throws IOException, InterruptedException {
InetAddress addr =
InetAddress.getByName(null);
while(true) {
if(JabberClientThread.threadCount()
MAX_THREADS)
new JabberClientThread(addr);
Thread.currentThread().sleep(100);
}
}
} ///:~
JabberClientThread構(gòu)建器獲取一個(gè)InetAddress,并用它打開(kāi)一個(gè)套接字。大家可能已看出了這樣的一個(gè)套路:Socket肯定用于創(chuàng)建某種Reader以及/或者Writer(或者InputStream和/或OutputStream)對(duì)象,這是運(yùn)用Socket的唯一方式(當(dāng)然,我們可考慮編寫一、兩個(gè)類,令其自動(dòng)完成這些操作,避免大量重復(fù)的代碼編寫工作)。同樣地,start()執(zhí)行線程的初始化,并調(diào)用run()。在這里,消息發(fā)送給服務(wù)器,而來(lái)自服務(wù)器的信息則在屏幕上回顯出來(lái)。然而,線程的“存在時(shí)間”是有限的,最終都會(huì)結(jié)束。注意在套接字創(chuàng)建好以后,但在構(gòu)建器完成之前,假若構(gòu)建器失敗,套接字會(huì)被清除。否則,為套接字調(diào)用close()的責(zé)任便落到了run()方法的頭上。
threadcount跟蹤計(jì)算目前存在的JabberClientThread對(duì)象的數(shù)量。它將作為構(gòu)建器的一部分增值,并在run()退出時(shí)減值(run()退出意味著線程中止)。在MultiJabberClient.main()中,大家可以看到線程的數(shù)量會(huì)得到檢查。若數(shù)量太多,則多余的暫時(shí)不創(chuàng)建。方法隨后進(jìn)入“休眠”狀態(tài)。這樣一來(lái),一旦部分線程最后被中止,多作的那些線程就可以創(chuàng)建了。大家可試驗(yàn)一下逐漸增大MAX_THREADS,看看對(duì)于你使用的系統(tǒng)來(lái)說(shuō),建立多少線程(連接)才會(huì)使您的系統(tǒng)資源降低到危險(xiǎn)程度。
服務(wù)器端接收客戶端的請(qǐng)求的話,需要在服務(wù)器端的java文件實(shí)現(xiàn)HttpServlet這個(gè)接口,并且在web.xml里配置一個(gè)客戶端的請(qǐng)求攔截。
web.xml里的代碼里添加
servlet
servlet-nametestServlet/servlet-name!--這個(gè)名字可以自己定--
servlet-classcom.sun.testServlet/servlet-class!--這里是你需要接收客戶端請(qǐng)求的那個(gè)類以及包名,也就是下面攔截到的url會(huì)轉(zhuǎn)發(fā)到的那個(gè)類--
/servlet
servlet-mapping
servlet-nametestServlet/servlet-name!--和上面的name需要一樣--
url-pattern/*/url-pattern!--什么類型的客戶端請(qǐng)求會(huì)被攔截,/*?就是全攔截了--
/servlet-mapping
然后再服務(wù)器端的類文件,要實(shí)現(xiàn) HttpServlet這個(gè)接口。并把doGet()方法和doPost()方法重寫。
這兩種方法分別對(duì)應(yīng)的是客戶端的get請(qǐng)求和post請(qǐng)求的處理,你的是post請(qǐng)求的話,就在doPost()方法內(nèi),寫你的業(yè)務(wù)。
然后再用下面兩句話,設(shè)置你要返回客戶端的數(shù)據(jù)。
//這是設(shè)置你要返回去的數(shù)據(jù)。value才是你的數(shù)據(jù),key是標(biāo)簽。
request.setAttribute("key", "value");
//這是設(shè)置你要返回去test.jsp這張頁(yè)面。
request.getRequestDispatcher("test.jsp").forward(request, response);
不知道你是不是這個(gè)意思,你可以再去看看相關(guān)servlet方面的知識(shí),
關(guān)于客戶端和服務(wù)器端大概也就是有個(gè)servlet作為請(qǐng)求的攔截
然后經(jīng)過(guò)相關(guān)判斷后,選擇性的傳到服務(wù)器的相應(yīng)類里面。
再經(jīng)過(guò)類里面的業(yè)務(wù),把得到需要的數(shù)據(jù)回傳到指定的頁(yè)面上。
Java平臺(tái)般三版本:Java ME(微型版用于某些手機(jī))、Java SE(標(biāo)準(zhǔn)版用于臺(tái)式電腦)、Java EE(企業(yè)版用于服務(wù)器端應(yīng)用)談Java我通指Java SE版本包含虛擬機(jī)編譯器
首先Java代碼編譯稱字節(jié)碼間格式字節(jié)碼目標(biāo)電腦運(yùn)行虛擬機(jī)快速解析目標(biāo)電腦硬件操作系統(tǒng)所需要本機(jī)格式
除發(fā)者提供編寫處運(yùn)行優(yōu)勢(shì)Java能通垃圾收器(GC)實(shí)現(xiàn)自內(nèi)存管理發(fā)者免手代碼釋放用象內(nèi)存雖功能非用且降低代碼引入內(nèi)存問(wèn)題風(fēng)險(xiǎn)增加運(yùn)行銷需要停執(zhí)行垃圾收進(jìn)程
本文比較Java SE用于Android發(fā)Java間差異首先我介紹發(fā)者習(xí)慣Java
SE語(yǔ)言結(jié)構(gòu)及何Android運(yùn)行其我介紹何優(yōu)化AndroidJava代碼何優(yōu)化內(nèi)存配及何恰處理線程
比較AndroidDalvik JavaJava SE
雖遠(yuǎn)Android現(xiàn)前發(fā)者能用Java編程語(yǔ)言移設(shè)備編寫應(yīng)用程序Java功能極限版本稱Java
ME(微型版)同移設(shè)備需編寫同代碼寫應(yīng)用程序能支持Java
ME任何手機(jī)運(yùn)行幾乎能外由于存線商店應(yīng)用發(fā)布程極其復(fù)雜
Android問(wèn)世發(fā)者提供構(gòu)建智能手機(jī)強(qiáng)應(yīng)用機(jī)發(fā)者需用Java編程語(yǔ)言及熟知標(biāo)準(zhǔn)Java
API編寫代碼盡管Android發(fā)者仍使用Java SE編譯器編譯應(yīng)用程序發(fā)現(xiàn)James
Gosling發(fā)JavaAndroid設(shè)備Java存許同處
Android設(shè)備運(yùn)行VM(虛擬機(jī))稱Dalvik初由谷歌Dan
Bornstein發(fā)適用于CPU內(nèi)存受限移設(shè)備Java SEDalvik Java存些差異主要體現(xiàn)虛擬機(jī)Java
SE使用棧機(jī)設(shè)計(jì)Dalvik設(shè)計(jì)基于寄存器機(jī)器Android SDKdx工具Java
SE棧機(jī)器字節(jié)碼轉(zhuǎn)換基于寄存器Dalvik機(jī)器字節(jié)碼該轉(zhuǎn)換步驟由IDE自完
基于棧虛擬機(jī)基于寄存器虛擬機(jī)定義及差異列入我討論范圍由于歷史原Android使用基于寄存器虛擬機(jī)雖基于寄存器虛擬機(jī)比基于棧虛擬機(jī)快32%限于執(zhí)行解釋字節(jié)碼虛擬機(jī)(說(shuō)解釋型虛擬機(jī))Android
2.2版本(稱Froyo)前Dalvik虛擬機(jī)都純解釋型Froyo版本引入JIT編譯器(即編譯)Java
SE早優(yōu)勢(shì)
JIT編譯稱態(tài)翻譯執(zhí)行前字節(jié)碼翻譯本機(jī)代碼(圖1所示)主要兩處首先消除些純解釋型虛擬機(jī)銷;其能本機(jī)代碼執(zhí)行優(yōu)化通靜態(tài)編譯代碼做例JIT編譯器運(yùn)行CPU選擇合適優(yōu)化根據(jù)應(yīng)用程序輸入析代碼何運(yùn)行便進(jìn)行步優(yōu)化
圖1 Android JavaJava SE翻譯步驟
雖AndroidDalvik JIT編譯器發(fā)展前景要達(dá)Java SEJIT編譯器般穩(wěn)定、熟度尚需段間Dalvik JIT現(xiàn)Android提供巨性能優(yōu)勢(shì)且斷改善
JAVA
SE虛擬機(jī)Dalvik虛擬機(jī)另區(qū)別者進(jìn)行優(yōu)化運(yùn)行同機(jī)器實(shí)例機(jī)啟叫做zygote進(jìn)程該進(jìn)程創(chuàng)建第Dalvik實(shí)例由實(shí)例創(chuàng)建所其實(shí)例應(yīng)用程序啟zygote進(jìn)程收創(chuàng)建新虛擬機(jī)實(shí)例請(qǐng)求并給該應(yīng)用程序創(chuàng)建新進(jìn)程(圖2所示)發(fā)者已習(xí)慣于Java
SE發(fā)設(shè)計(jì)能看起切實(shí)際優(yōu)勢(shì)避免由應(yīng)用程序運(yùn)行失敗導(dǎo)致Dalvik虛擬機(jī)崩潰繼引發(fā)應(yīng)用程序崩潰
圖2 Android啟新Dalvik虛擬機(jī)實(shí)例
AndroidJava
SE除運(yùn)行虛擬機(jī)同外實(shí)現(xiàn)API式Android屬于javajavax包API都自Apache
Harmony(源項(xiàng)目旨重新實(shí)現(xiàn)Java SE軟件棧該項(xiàng)目201111月再維護(hù))發(fā)面些APIJava
SE包類似存些差別例谷歌HttpUrlConnection類進(jìn)行Java SE版本所沒(méi)重升級(jí)
外Android平臺(tái)移除Java
SE關(guān)API例Swing/AWT包完全移除Android使用同UI框架其移除APIRMI、CORBA、ImageIOJMX或者替換特定Android版本(android包空間內(nèi))或者些實(shí)際原根本存
優(yōu)化AndroidJava代碼
經(jīng)改進(jìn)Java
SE具備些簡(jiǎn)化編寫復(fù)雜代碼結(jié)構(gòu)新特性其些特性讓整流程變更簡(jiǎn)單發(fā)者需要解何及何確使用另外由于Java
SE用于服務(wù)器端發(fā)(使用Java企業(yè)版API)發(fā)員專門服務(wù)器端Java代碼進(jìn)行優(yōu)化注解Java虛擬機(jī)腳本語(yǔ)言支持服務(wù)器端發(fā)進(jìn)行優(yōu)化例證雖些工具構(gòu)建端發(fā)強(qiáng)發(fā)Android客戶端代碼些特性作用甚至起反作用Java發(fā)者已經(jīng)習(xí)慣于限量RAMCPUAndroid發(fā)需要密切關(guān)注性能內(nèi)存配簡(jiǎn)單說(shuō)發(fā)者需要使用稍微同待Android端發(fā)
隨著Android首發(fā)布情況所改變?cè)?jīng)些Android盡量用Java規(guī)范重新推薦主要Android目前JIT編譯器解決些規(guī)范導(dǎo)致性能問(wèn)題
本文討論編寫Android應(yīng)用程序需要解Java代碼我深究Java編程語(yǔ)言細(xì)節(jié)重點(diǎn)關(guān)注Android發(fā)重要東西發(fā)者仍需解數(shù)適用于Java SE規(guī)則建議同適用于AndroidDalvik虛擬機(jī)
Android類型安全枚舉
Java SE 5.0新增許便發(fā)者新特性其值期待引入類型安全枚舉枚舉代碼用表示屬于某組幾選擇早期版本Java用整型量解決問(wèn)題雖技術(shù)行容易錯(cuò)請(qǐng)看面代碼:
public class Machine {
public static final int STOPPED = 10;
public static final int INITIALIZING = 20;
public static final int STARTING = 30;
public static final int RUNNING = 40;
public static final int STOPPING = 50;
public static final int CRASHED = 60;
private int mState;
public Machine() {
mState = STOPPED;
}
public int getState() {
return mState;
}
public void setState(int state) {
mState = state;
}
}
問(wèn)題雖些量期望沒(méi)機(jī)制保證setState()接收同值要設(shè)置添加檢查旦非預(yù)期值發(fā)者需要處理錯(cuò)誤發(fā)者所需要編譯檢查非賦值類型安全枚舉解決問(wèn)題所示:
public class Machine {
public enum State {
STOPPED, INITIALIZING, STARTING, RUNNING, STOPPING, CRASHED
}
private State mState;
public Machine() {
mState = State.STOPPED;
}
public State getState() {
return mState;
}
public void setState(State state) {
mState = state;
}
}
注意聲明同類型安全值新加內(nèi)部枚舉類編譯解決非賦值問(wèn)題所代碼更容易錯(cuò)
Dalvik虛擬機(jī)沒(méi)JIT編譯器優(yōu)化代碼建議Android平臺(tái)使用枚舉類型使用整型量相比種設(shè)計(jì)帶內(nèi)存性能損失更些版本Android
API存整型量原今更強(qiáng)JIT編譯器及斷改進(jìn)Dalvik虛擬機(jī)發(fā)者必再擔(dān)問(wèn)題放膽使用類型安全枚舉即
仍存些情況使用整型量更選擇像intJava基本類型增加GC銷外Android SDK許已API仍依賴基本類型比Handler類——種情況沒(méi)太選擇
Android增強(qiáng)版for循環(huán)
Java SE 5.0引入增強(qiáng)版for循環(huán)提供通用縮寫表達(dá)式遍歷集合數(shù)組首先比較五種:
void loopOne(String[] names) {
int size = names.length;
for (int i = 0; i size; i++) {
printName(names[i]);
}
}
void loopTwo(String[] names) {
for (String name : names) {
printName(name);
}
}
void loopThree(Collection names) {
for (String name : names) {
printName(name);
}
}
void loopFour(Collection names) {
Iterator iterator = names.iterator();
while (iterator.hasNext()) {
printName(iterator.next());
}
}
// 要ArrayList使用增強(qiáng)版for循環(huán)
void loopFive(ArrayList names) {
int size = names.size();
for (int i = 0; i size; i++) {
printName(names.get(i));
}
}
面顯示四種同遍歷集合數(shù)組式前面兩種著相同性能所讀取元素放數(shù)組使用增強(qiáng)版for循環(huán)Collection象說(shuō)增強(qiáng)版for循環(huán)使用迭代器遍歷元素著相同性能ArrayList象應(yīng)避免使用增強(qiáng)版for循環(huán)
僅需要遍歷元素且需要元素位置定要使用數(shù)組或者ArrayList所其Collection類些情況更慢
般情況讀取元素幾乎變數(shù)據(jù)集性能要求高建議使用規(guī)數(shù)組數(shù)組固定添加數(shù)據(jù)影響性能所編寫代碼要考慮所素
隊(duì)列、同步鎖
通情況應(yīng)用程序線程產(chǎn)數(shù)據(jù)另線程使用見(jiàn)例線程獲取網(wǎng)絡(luò)數(shù)據(jù)另線程(操作UI主線程)些數(shù)據(jù)展現(xiàn)給用戶種模式稱產(chǎn)者/消費(fèi)者模式面向象編程課程發(fā)者用算實(shí)現(xiàn)該模式能要花幾面介紹些簡(jiǎn)化產(chǎn)者/消費(fèi)者模式實(shí)現(xiàn)現(xiàn)類
1. 更智能隊(duì)列
雖已現(xiàn)類并能用更少代碼實(shí)現(xiàn)該功能許Java發(fā)者仍選擇使用LinkedList及同步塊實(shí)現(xiàn)隊(duì)列功能發(fā)者java.util.concurrent包找同步相關(guān)類外本包包含信號(hào)量、鎖及單變量進(jìn)行原操作類考慮面使用標(biāo)準(zhǔn)LinkedList實(shí)現(xiàn)線程安全隊(duì)列代碼
public class ThreadSafeQueue {
private LinkedList mList = new LinkedList();
private final Object mLock = new Object();
public void offer(String value) {
synchronized (mLock) {
mList.offer(value);
mLock.notifyAll();
}
}
public synchronized String poll() {
synchronized (mLock) {
while (mList.isEmpty()) {
try {
mLock.wait();
} catch (InterruptedException e) {
//簡(jiǎn)潔起見(jiàn)忽略異處理
}
}
return mList.poll();
}
}
}
雖段代碼確并能考試滿實(shí)現(xiàn)測(cè)試段代碼浪費(fèi)間實(shí)際所前面代碼用面行代替
LinkedBlockingQueue blockingQueue =
new LinkedBlockingQueue();
面行代碼能像前面例提供相同類型阻塞隊(duì)列甚至能提供額外線程安全操作java.util.concurrent包含許選隊(duì)列及并發(fā)映射類所般情況建議使用像前示例使用更代碼
2. 更智能鎖
Java提供synchronized關(guān)鍵字允許發(fā)者創(chuàng)建線程安全代碼塊synchronized關(guān)鍵字易于使用容易濫用性能造負(fù)面影響需要區(qū)讀數(shù)據(jù)寫數(shù)據(jù)synchronized關(guān)鍵字并效幸java.util.concurrent.locks包工具類種情況提供支持
public class ReadWriteLockDemo {
private final ReentrantReadWriteLock mLock;
private String mName;
private int mAge;
private String mAddress;
public ReadWriteLockDemo() {
mLock = new ReentrantReadWriteLock();
}
public void setPersonData(String name, int age, String address) {
ReentrantReadWriteLock.WriteLock writeLock = mLock.writeLock();
try {
writeLock.lock();
mName = name;
mAge = age;
mAddress = address;
} finally {
writeLock.unlock();
}
}
public String getName() {
ReentrantReadWriteLock.ReadLock readLock = mLock.readLock();
try {
readLock.lock();
return mName;
} finally {
readLock.unlock();
}
}
// 重復(fù)代碼再贅述
}
面代碼展示使用ReentrantReadWriteLock允許并發(fā)線程數(shù)據(jù)進(jìn)行讀訪問(wèn)并確保同間線程寫入相同數(shù)據(jù)
代碼使用synchronized關(guān)鍵字仍處理鎖問(wèn)題效論何種情況都要考慮ReentrantReadWriteLock否
注:以下代碼,除FileFilter是編譯并測(cè)試過(guò)的,其它代碼未在IDE中編寫,所以可能會(huì)有問(wèn)題,自己試下
String dirname = "d:\\abc";
File dir = new File(dirname);
String suffix = ".abc";
String dst = ".def";
File[] files = dir.list(new FileFilter(suffix, false);
for (File file : files) {
String newName = file.getAbsolutePath().replace(suffix, dst);
file.renameTo(new File(newName));
}
/**
* p標(biāo)題: FileFilter./p
*
* p描述: 文件過(guò)濾器/p
*
* p版權(quán): Copyright (c) 2006/p
*
* @author BlazeCrystal
*
* @version 1.0.0
*/
public class FileFilter implements java.io.FileFilter {
public static final int ALL = 0;
public static final int ONLY_DIR = 1;
public static final int ONLY_FILE = 2;
/**
* 過(guò)濾器.
*/
private String nameFilter;
/**
* 是否大小寫敏感.
*/
private boolean capSense;
/**
* 類型過(guò)濾器.
*/
private int typeFilter;
/**
*
* 構(gòu)造函數(shù).
*
* @param nameFilter String 名稱過(guò)濾器
* @param capSense boolean 是否大小寫敏感
*/
public FileFilter(String nameFilter, boolean capSense) {
this.capSense = capSense;
if (this.capSense) {
this.nameFilter = nameFilter;
} else {
this.nameFilter = nameFilter.toLowerCase();
}
this.typeFilter = ALL;
}
/**
*
* 構(gòu)造函數(shù).
*
* @param nameFilter String 名稱過(guò)濾器
* @param capSense boolean 是否大小寫敏感
* @param typeFilter int 類型過(guò)濾器
*/
public FileFilter(String nameFilter, boolean capSense, int typeFilter) {
this.capSense = capSense;
if (this.capSense) {
this.nameFilter = nameFilter;
} else {
this.nameFilter = nameFilter.toLowerCase();
}
this.typeFilter = typeFilter;
}
/**
*
* 構(gòu)造函數(shù).
*
* @param typeFilter int 類型過(guò)濾器
*/
public FileFilter(int typeFilter) {
this.typeFilter = typeFilter;
}
/**
* 過(guò)濾.
*
* @param file File 當(dāng)前文件
* @return boolean 是否應(yīng)選擇
*/
public boolean accept(File file) {
boolean accept = true;
if (this.typeFilter != 0) {
accept = filterByType(file);
}
if (!StringUtils.isEmpty(this.nameFilter)) {
accept = filterByName(file);
}
return accept;
}
/**
* 用名稱過(guò)濾.
*
* @param file File 文件
* @return boolean 是否保留
*/
public boolean filterByName(File file) {
String temp = null;
if (this.capSense) {
temp = file.getName();
} else {
temp = file.getName().toLowerCase();
}
if (temp.indexOf(this.nameFilter) -1) {
return true;
}
return false;
}
/**
* 用類型過(guò)濾.
*
* @param file File 當(dāng)前文件
* @return boolean 是否保留
*/
public boolean filterByType(File file) {
switch (this.typeFilter) {
case ONLY_DIR:
return file.isDirectory();
case ONLY_FILE:
return file.isFile();
default:
return true;
}
}
/**
* 獲得nameFilter.
*
* @return nameFilter
*/
public String getNameFilter() {
return nameFilter;
}
/**
* 設(shè)置nameFilter.
*
* @param nameFilter 要設(shè)置的 nameFilter
*/
public void setNameFilter(String nameFilter) {
this.nameFilter = nameFilter;
}
/**
* 獲得capSense.
*
* @return capSense
*/
public boolean isCapSense() {
return capSense;
}
/**
* 設(shè)置capSense.
*
* @param capSense 要設(shè)置的 capSense
*/
public void setCapSense(boolean capSense) {
this.capSense = capSense;
}
/**
* 獲得typeFilter.
*
* @return typeFilter
*/
public int getTypeFilter() {
return typeFilter;
}
/**
* 設(shè)置typeFilter.
*
* @param typeFilter 要設(shè)置的 typeFilter
*/
public void setTypeFilter(int typeFilter) {
this.typeFilter = typeFilter;
}
}
新聞標(biāo)題:服務(wù)器編寫java代碼 服務(wù)器編寫java代碼命令
分享網(wǎng)址:http://chinadenli.net/article22/doopocc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供定制開(kāi)發(fā)、營(yíng)銷型網(wǎng)站建設(shè)、服務(wù)器托管、品牌網(wǎng)站制作、網(wǎng)站建設(shè)、自適應(yīng)網(wǎng)站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)