JAVA : Socket和多线程

这几天面试老是被问到你对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;
    }

}

Server代码:

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
        
    }
    
    
}

Client:

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();
           }
    }
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值