Java5增加了新的类库并发集java.util.concurrent,该类库为并发程序提供了丰富的API,多线程编程在Java 5中更加容易,灵活。
以下是一个范例的源码。
1、Server类源码
package com.jeyo.java5;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Server {
public static final int PORT = 19788;
private ExecutorService pool = null;
private ServerSocket serverSocket = null;
public void start(){
//创建一个可重用固定线程数的线程池
pool = Executors.newFixedThreadPool(10);
//创建一个可根据需要创建新线程的线程池
//pool = Executors.newCachedThreadPool();
try{
serverSocket = new ServerSocket();
serverSocket.setReuseAddress(true);
serverSocket.bind(new InetSocketAddress(PORT));
System.out.println("开始监听...");
while(true){
Socket socket = serverSocket.accept(); //获取客户端线程,没有则等待
//异步执行
//要是线程池繁忙,是等待还是终止?
pool.execute(new ServiceThread(socket));
}
}catch(Exception e){
e.printStackTrace();
}
cleanup();
}
public void cleanup() {
if(serverSocket != null){
try{
serverSocket.close(); //关闭服务器线程
}catch(IOException e){
e.printStackTrace();
}
}
pool.shutdown(); //关闭线程池
}
public static void main(String args[]) {
Server server = new Server();
server.start();
}
}
2、ServiceThread类源码
package com.jeyo.java5;
import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.Serializable;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.locks.ReentrantLock;
public class ServiceThread implements Runnable, Serializable {
private static final long serialVersionUID = 0;
private Socket connectedSocket = null;
private static int count = 0;
private static ReentrantLock lock = new ReentrantLock(); //重入锁:是一种递归无阻塞的同步机制
ServiceThread(Socket socket) {
connectedSocket = socket;
}
public void run(){
increaseCount();
int curCount = getCount();
String helloString = "最新序列号:" + curCount + "\n";
//该对象只有一个线程可用来执行任务,若任务多于一个,任务将按先后顺序执行
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<String> future = executor.submit(new OtherTask()); //异步执行其它逻辑代码
DataOutputStream out = null;
try{
//往客户端线程输出信息
out = new DataOutputStream(connectedSocket.getOutputStream());
out.write(helloString.getBytes());
//获取客户端传送过来的信息
DataInputStream reader = new DataInputStream(new BufferedInputStream(connectedSocket.getInputStream()));
System.out.println(reader.readUTF());
try{
out.write("其它任务的结果:\n".getBytes());
String result = future.get(); //同步获取任务结果
out.write(result.getBytes());
}catch(Exception e){
e.printStackTrace();
}
}catch(Exception e){
e.printStackTrace();
}finally{
if(out != null){
try{
out.close(); //关闭输出流
}catch(Exception e){
e.printStackTrace();
}
}
executor.shutdown(); //关闭线程执行器
}
}
private int getCount() {
int ret = 0;
try{
lock.lock();
ret = count;
}finally{
lock.unlock(); //切记要在finally中释放锁
}
return ret;
}
private void increaseCount() {
try{
lock.lock();
++count;
}finally{
lock.unlock();
}
}
}
3、OtherTask类源码
package com.jeyo.java5;
import java.util.concurrent.Callable;
public class OtherTask implements Callable<String> {
public String call() throws Exception {
return "执行了其它逻辑代码。";
}
}
4、Client类源码
package com.jeyo.java5;
import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
public class Client {
private Socket client;
public Client(String host, int port){
try{
client = new Socket(host, port);
}catch(IOException e){
System.out.println("服务器连接失败!");
close();
}
}
public void send(){
DataOutputStream out = null;
try{
//往服务器发送信息
out = new DataOutputStream(client.getOutputStream());
out.writeUTF("中国");
out.flush();
//获取服务器传送过来的信息
DataInputStream reader = new DataInputStream(new BufferedInputStream(client.getInputStream()));
int bufferSize = 2048; //2K
byte[] buf = new byte[bufferSize];
int read = 0;
while((read=reader.read(buf)) != -1){
System.out.println(new String(buf, 0, read));
}
}catch(IOException ex){
ex.printStackTrace();
}finally{
try{
out.close();
}catch(IOException e){
e.printStackTrace();
}
close();
}
}
private void close(){
if(client != null){
try{
client.close();
}catch(IOException e){
e.printStackTrace();
}
}
}
public static void main(String[] args) {
Client client = new Client("localhost", Server.PORT);
client.send();
}
}