七、JSP与SERVLET
1. 通过init方法缓存静态数据
2. 用print代替println,用ServletOutputStream代替 PrintWriter,因为不需要再把字符流转为字节流,提高效率;如果要用PrintWriter,最好这样:
ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);
PrintWriter pw = new PrintWriter(baos);
3. flush()之后数据才发完,这时候可以部分输出。即
ServletOutputStream Out = res.getOutputStream();
Out.write(header);
Out.flush;
Out.write(gif);
Out.flush;
Out.write(footer);
Out.flush;
4.减少同步代码的数量
5. 设置合适的响应内容长度response.setContentLength()
6. 缓存静态数据与动态数据:session,application,应用服务器的设置
但是要注意数据可能与数据库中的不一致,需要定时更新。
session.setAttribute() session.getAttribute()
7.不要使用singlethreadmodel,尽量用threadpool,每次servlet引擎会把一个线程指派给一个请求然后放回池中。
8. Filter listener的使用
十、JDBC与性能优化
1、 使用数据库连接池改善效率,并及时关闭连接对象,合理选择事务(ACID,减少不必要的commit)
2、 优化statement:
当需要成批处理重复插入或者更新操作或者有大量用户重复操作时,采用PreparedStatement,只编译解析一次命令,然后放到命令缓冲区。
尽可能批处理更新:addBatch(),executeBatch()
采用适当数据缓存:setFetchSize(),getFetchSize()每次以增量的方式获取结果集,不必要重复查询
3、 优化resultset:
设置数据缓冲、处理数据行的方向(减少定位消耗)、getXX()
十一、软件结构、设计模式、性能优化
常用的设计模式:
AbstractFactory, Singleton, Adapter, Proxy, Bridge, Command, Observer, Chain ofResponsibility, Mediator, Visitor
任务分配中心模式:
分离具体请求和处理者,松散耦合,在三层web应用体系中十分有用。
public class TaskAssignmentCenter{
private Request request = null;
public void acceptRequest(Request request)
{
this.request = request;
}
public void assignTask()
{
//after receive the request, find the description of this task, and call concrete handler to handle this task.
String requestObjective = request.getRequestObjective();
/*if(requestObjective.equals("Atask"))
{
new ConcreteHandlerA().handleRequest(request);
}
else if(requestObjective.equals("Btask"))
{
new ConcreteHandlerB().handleRequest(request);
}*/
java.util.Properties prop = ConfigUTL.getConfigInfo();
try{
Handler handler = (Handler) Class.forName(prop.getProperty(requestObjective)).newInstance();
handler.handleRequest(request);
}
catch(Exception e)
{
e.printStackTrace();
}
}
public static void main(String [] args)
{
ConcreteRequestA cra = new ConcreteRequestA();
cra.setRequestObjective("Atask");
ConcreteRequestB crb = new ConcreteRequestB();
crb.setRequestObjective("Btask");
ConcreteRequestC crc = new ConcreteRequestC();
crc.setRequestObjective("Ctask");
TaskAssignmentCenter tac = new TaskAssignmentCenter();
tac.acceptRequest(cra);
tac.assignTask();
tac.acceptRequest(crb);
tac.assignTask();
tac.acceptRequest(crc);
tac.assignTask();
}
}
import java.io.*;
import java.util.Properties;
public class ConfigUTL{
private static Properties prop = new Properties();
private static boolean isLoaded = false;
public static Properties getConfigInfo()
{
return prop;
}
static {
if(!isLoaded)
{
try{
InputStream is = new ConfigUTL().getClass().getResourceAsStream("RequestAndHandler.conf");
prop.load(is);
isLoaded = true;
}
catch(IOException e)
{
isLoaded = false;
e.printStackTrace();
}
}
}
}
public interface Request
{
public void setRequestObjective(String objective);
public String getRequestObjective();
}
public class ConcreteRequestA implements Request{
private String objective = null;
public void setRequestObjective(String objective)
{
this.objective = objective;
}
public String getRequestObjective()
{
return this.objective;
}
}
public class ConcreteRequestB implements Request{
private String objective = null;
public void setRequestObjective(String objective)
{
this.objective = objective;
}
public String getRequestObjective()
{
return this.objective;
}
}
public interface Handler
{
public void handleRequest(Request request);
}
public class ConcreteHandlerA implements Handler{
public void handleRequest(Request request)
{
System.out.println("handler A handle task A!");
}
}
public class ConcreteHandlerB implements Handler{
public void handleRequest(Request request)
{
System.out.println("handler B handle task B!");
}
}
RequestAndHandler.conf中的内容:可以继续添加C
Atask = ConcreteHandlerA
Btask = ConcreteHandlerB
Ctask = ConcreteHandlerC
十二、多线程
1. 线程状态:init,start,running,wait,dead;
3. 线程池 (线程池管理器、线程池、工作线程、任务接口等组成)
资源允许的情况下,选择并发请求数量的峰值作为线程池的大小。但是要考虑资源。
线程池管理器功能:创建线程池实例,销毁,只有一个线程池管理器实例。
线程池功能:初始化,缓存待命线程,提供待命线程,唤醒线程处理任务。
如下是线程池的一个简单实现:
public class PoolAdvanceServer{
public static int clientCount = 0;
static int port = 7654;
ThreadPool threadPool = PoolManager.getInstance().createThreadPool(100,ServerWorker.class);
public void listenServer(int port) throws Exception
{
ServerSocket sSocket = new ServerSocket(port);
System.out.println("advanced server is listening port " + port);
while(true)
{
clientCount++;
threadPool.performWork(sSocket.accept());
}
}
public static void main(String[] args)
{
}
}
public class PoolManager
{
private static PoolManager instance = null;
private PoolManager()
{
}
//only one pool manager
public static PoolManager getInstance()
{
if(instance == null)
instance = new PoolManager();
return instance;
}
//get thread pool
public ThreadPool creatThreadPool(int max, Class worker)
{
ThreadPool threadPool = null;
try{
threadPool = new ThreadPool(max,worker)
}
catch(Exception e)
{
e.printStackTrace();
}
return threadPool;
}
}
public class ThreadPool
{
//the threat to work
class WorkerThread extends Thread{
private Worker _worker;
private Object _data;
WorkerThread(String id, Worker worker)
{
super(id);
_worker = worker;
_data = null;
}
//wake this thread and do some work
synchronized void wake(Object data)
{
_data = data;
notify();
}
synchronized public void run()
{
boolean stop = false;
while(!stop)
{
//when init, all work thread is waiting
if(_data == null)
{
try{
wait();
}
catch(Exception e)
{
e.printStackTrace();
continue;
}
}
//after performWork wake this thread, it ask worker to do some work
if(_data != null)
{
System.out.println(this.getName);
_worker.run(_data);
}
_data = null;
//work over, return this thread to stack, if ok, this thread continues to wait; else kill this thread
stop = !(_push(this));
}
}
}
//thread in preparation
private Stack _waiting;
private int _max;
//worker class
private Class _workerClass;
public ThreadPool(int max, Class workerClass) throws Exception
{
_max = max;
//create a stack for waiting thread
_waiting = new Stack();
//equals to serverworker
_workerClass = workerClass;
//worker do some work
Worker worker;
//controls worker
WorkerThread w;
//create max threads , waiting
for(int i = 0; i < _max; i ++)
{
worker = (Worker)_workerClass.newInstance();
w = new WorkerThread("Worker#" + i, worker);
w.start();
_waiting.push(w);
}
}
//pop one waiting thread
public void performWork(Object data ) throws InstantiationException{
WorkerThread w = null;
synchronized (_waiting)
{
if(_waiting.empty())
{
try{
w = new WorkerThread("additional worker", (Worker)_workerClass.newInstance());
w.start();
}
catch(Exception e)
{
throw new InstantiationException("problem creating instance of Worker.class: " + e.getMessage());
}
}
else{
w = (WorkerThread) _waiting.pop();
}
}
//wake this work thread
w.wake(data);
}
//return thread to the stack
private boolean _push(WorkerThread w)
{
boolean stayAround = false;
synchronized (_waiting)
{
if(_waiting.size() < _max)
{
stayAround = true;
_waiting.push(w);
}
}
return stayAround;
}
}
public interface Worker{
public void run(Object data);
}
public class ServerWorker implements Worker
{
public void run(Object data)
{
processRequest((Socket) data);
}
//this worker do it's work
private void processRequest(Socket socket)
{
try{
InputStream ins = socket.getInputStream();
OutputStream os = socket.getOutputStream();
DataInputStream dis = new DataInputStream(ins);
DataOutputStream dos = new DataOutputStream(os);
int receiveInt = dis.readInt();
System.out.println("this message is from client " + PoolAdvanceServer.clientCount + " : " + receiveInt);
dos.writeInt(receiveInt * 18);
dos.flush();
dos.close();
dis.close();
ins.close();
delay(101);
PoolAdvanceServer.clientCount --;
}
catch(Exception e)
{
e.printStackTrace();
}
}
private void delay(long delayCount)
{
try{
Thread.sleep(delayCount);
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
十三、泛型与应用优化(JDK1.5)
1. 支持定义带有抽象数据类型参数的类,提供了程序的类型安全且易兼容
在编译时进行类型检查,提高程序可靠性。
2. 避免强制类型转换:原来在用集合时对象放入后成为Object实例,取出时转换繁琐。
3. 性能提升:初始实现是把强制类型转换插入字节码中,get()返回值类型指明。
4. 基本数据类型自动pack,unpack,可以限制泛型中类型参数的范围,如V extends Number
class Parent{
private Parent()
{
System.out.println("private ");
}
}
//generic
public class Test<K extends String, V extends Number> //forbidden: extends Parent, because subclass cannot call superclass's private method
{
private V v = null;
private K k = null;
public static void main(String[] args)
{
Test t = new Test();
t.k = "test";
t.v = 12.3;
System.out.println(t.k);
System.out.println(t.v);
}
}