这几天面试老是被问到你对Java并发和网络编程熟不熟。
姐比较实诚,我直明,看过资料,没动过手,于是被鄙视之。 = =以后我的博客应该叫荒废一年的IT女码农边学边面。。。
干脆回来花了点时间写了程序,练个手。
Socket Server 处理多个Socket client的写入请求,然后Socket Server将读取的数据写入一个和client共享的Queue中。也就是server是这个Queue的生产者,Client又是这个Queue的消费者。
Queue代码:
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class SafeQueue {
private final Byte[] buffer;
private int size;
private int capacity;
private int start;
private int end;
private ReentrantLock lock;
private Condition notFull;
private Condition notEmpty;
private static SafeQueue queue;
private SafeQueue(int size) {
this.size = size;
this.capacity = size;
this.start = 0;
this.end = 0;
buffer = new Byte[size];
lock = new ReentrantLock(true);
notFull = lock.newCondition();
notEmpty = lock.newCondition();
}
public static SafeQueue getSingleInstance() {
if (queue == null) {
queue = new SafeQueue(20);
for (int i = 0; i < 20; i++ ) {
try {
queue.put((byte)i);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
return queue;
}
public void put(Byte newElement) throws InterruptedException {
ReentrantLock lock = this.lock;
lock.lockInterruptibly();
try {
try {
while (capacity == 0) {
notFull.await();
}
} catch (InterruptedException e) {
notFull.signal();
e.printStackTrace();
}
buffer[end] = newElement;
end = (end + 1) % this.size;
capacity--;
notEmpty.signal();
}
finally{
lock.unlock();
}
}
public Byte peek() {
ReentrantLock lock = this.lock;
lock.lock();
try {
try {
if(capacity == size) {
notEmpty.await();
}
} catch (InterruptedException e) {
notEmpty.signal();
}
Byte result = null;
result = buffer[start];
buffer[start] = null;
start = (start + 1) % size;
capacity++;
notFull.signal();
return result;
} finally {
lock.unlock();
}
}
public byte[] peek(int length) {
ReentrantLock lock = this.lock;
lock.lock();
try{
byte[] result = new byte[length];
for(int i = 0; i < length; i++) {
try {
if(capacity == size) {
notEmpty.await();
}
} catch (InterruptedException e) {
notEmpty.signal();
}
result[i] = buffer[start];
buffer[start] = null;
start = (start + 1) % size;
capacity++;
notFull.signal();
}
return result;
}
finally{
lock.unlock();
}
}
public void put(byte[] elements, int length) throws InterruptedException {
ReentrantLock lock = this.lock;
lock.lockInterruptibly();
try {
for (int i = 0; i < length; i++) {
try {
while (capacity == 0) {
notFull.await();
}
} catch (InterruptedException e) {
notFull.signal();
e.printStackTrace();
}
buffer[end] = elements[i];
end = (end + 1) % this.size;
capacity--;
notEmpty.signal();
}
}
finally{
lock.unlock();
}
}
public int size() {
ReentrantLock lock = this.lock;
lock.lock();
try {
return size - capacity;
}
finally{
lock.unlock();
}
}
public String toString() {
String re = "";
for (int i = 0; i < 20; i++) {
re+=buffer[i]+ "|";
}
return re;
}
}
import java.io.BufferedInputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Server extends Thread {
ServerSocket server;
/**
* @param args
*/
//写个Socket发送数据
public Server() {
try {
server = new ServerSocket(9994);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void run() {
Socket socket = null;
while(true) {
try {
socket = server.accept();
executorService.execute(new DealThread(socket));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
new Server().start();
}
}
class DealThread implements Runnable {
Socket socket = null;
SafeQueue queue = SafeQueue.getSingleInstance();
public DealThread(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
try {
byte[] result = new byte[5];
System.out.println("New connection accepted "+socket.getInetAddress()+":"+socket.getPort()+ socket.getReceiveBufferSize());
BufferedInputStream reader = new BufferedInputStream(socket.getInputStream());
int length = reader.read(result, 0, result.length);
while(length >= 0) {
try {
queue.put(result, length);
System.out.println("server: " + queue);
length = reader.read(result, 0, result.length);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// TODO Auto-generated method stub
}
}
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Customer {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
new Server().start();
ExecutorService executorService = Executors.newFixedThreadPool(10);
for(int i = 0; i< 4; i++) {
executorService.execute(new CustomerThread());
}
}
}
class CustomerThread implements Runnable {
Socket socket;
SafeQueue queue = SafeQueue.getSingleInstance();
public CustomerThread() {
try {
socket = new Socket(InetAddress.getLocalHost(), 9994);
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public void run() {
while(true) {
byte[] result = queue.peek(5);
BufferedOutputStream writer = null;
try {
writer = new BufferedOutputStream(socket.getOutputStream());
writer.write(result);
writer.flush();
System.out.println(queue);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}