java项目代码

叶雁1314 贡献于2012-06-28

作者 微软中国  创建于2010-06-01 14:07:00   修改者微软中国  修改于2010-06-01 14:16:00字数14235

文档摘要:消费者与生产者问题生产者与消费者问题,听说是讲线程的一个经典问题.简单来说,有生产者,消费者,生产者不断的生产消费者不断的消费.要用代码模拟这一过程.建立了5个类Productor(生产者)Consumer(消费者)Warehouse(仓库)Something(物品)ProductorAndConsumer(main()函数所在类) 本代码从最基本的实现开始逐步完善,修改N次,多个产品多个仓库也是可以的.只不过,和我曾想象的实现不太一样.喜欢研究的朋友自己做测试吧.
关键词:

消费者与生产者问题 生产者与消费者问题,听说是讲线程的一个经典问题.简单来说,有生产者,消费者,生产者不断的生产消费者不断的消费.要用代码模拟这一过程. 建立了5个类 Productor(生产者) Consumer(消费者) Warehouse(仓库) Something(物品) ProductorAndConsumer(main()函数所在类)  本代码从最基本的实现开始逐步完善,修改N次,多个产品多个仓库也是可以的.只不过,和我曾想象的实现不太一样. 喜欢研究的朋友自己做测试吧. 部分代码已经修改  用蓝字标出2009.12.12 package test; /* 生产者消费者问题--消费者  * @author yeS  * @version 1.0.0  */ public class Consumer implements Runnable {  /*   * 消费地点: w仓库   * 消费物品: s   * 一次消费数量: num   * 计划消费总数: total   */  private Warehouse w;  private Something s;  private int num;  private int total;  // 构造函数  Consumer(Warehouse w, Something s, int num, int total) {   this.w = w;   this.s = s;   this.num = num;   this.total = total;  }  /*   * 开始消费   *   * 等待生产 1)仓库内有物品 -> A)消费计划未完成 -> 消费 -> 输出消费信息 -> 1)   *                     -> B)消费计划完成 -> 结束 -> 2)        *         2)仓库内没有物品 -> 结束   */  public void run() {   // 记录消费次数   int count = 0;   while(total != (count*num)) {        w.takeOut(s, num);    count++;    System.out.println("第" + count + "次消费----Consumer : 我从第"      + w.getID() + "号仓库,拿了" + num + "个" + s.getName());   }  } } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ package test; /* 生产者消费者问题--生产者  * @author yeS  * @version 1.0.0  */ public class Productor implements Runnable {  /*   * 生产者要生产的物品 s   * 生产的时间,即次数 t   * 每次生产的物品数量 num   * 存放物品的仓库     w   */  private Something s;  private int t;  private int num;  private Warehouse w;  private boolean ProductorInfo = false;  // 构造函数  Productor(Something s, int t, int num, Warehouse w) {   this.s = s;   this.t = t;   this.num = num;   this.w = w;  }  /*   * 开始生产   *   * 生产过程: 1)生产出物品 -> 放到仓库里 -> 通知我的生产信息 -> A)达到要求的供货数量 -> 停止生产   *                                                     B)没有达到要求供货数量 -> 1)   */  public void run() {      for (int i = 0; i < t; i++) {    s.setNumber(num);    w.add(s);    System.out.println("第" + (i+1) + "次生产----" + "Productor : 我生产了" + num + "个" + s.getName()      + ",放在了" + w.getID() + "号仓库中");        if (i == (t-1)) {     ProductorInfo = true;     System.out.println("供货结束----我总共生产了" + 10 * num + "个" + s.getName());    }   }  } } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ package test; /* 生产者消费者问题--仓库  * @author yeS  * @version 1.0.0  */ public class Warehouse {    /*   *  仓库号            id   *  仓库的容量        capacity   *  仓库总物品的数量  total   */  private int id;  private int capacity;  private int total;    //仓库的构造函数  Warehouse(int id, int capacity) {   this.id = id;   this.capacity = capacity;  }    /*   * 这里wait()的使用,需要满足几个条件   * 1,包含wait()的代码必须锁定,应锁定在判断句外,锁定代码和方法均可,   * 2,必须使用notifyAll()或者是notify(),推荐使用notifyAll().   *   *  网上说:      wait()      是使持有对象锁的线程释放锁;   wait(long)  是使持有对象锁的线程释放锁时间为long(毫秒)后,再次获得锁,wait()和wait(0)等价;   notify()    是唤醒一个正在等待该对象锁的线程,如果等待的线程不止一个,那么被唤醒的线程由jvm确定;   notifyAll   是唤醒所有正在等待该对象锁的线程.      并且应该优先使用notifyAll()方法,因为唤醒所有线程比唤醒一个线程更容易让jvm找到最适合被唤醒的线程 .   对于上述方法,只有在当前线程中才能使用,否则报运行时错误   */    //向仓库添加物品  synchronized void add(Something s) {      int sum = total + s.getNumber();   if (total == capacity || sum > capacity) {    System.out.println("仓库物品已满,请等待");    try {     wait();    } catch (InterruptedException e) {     e.printStackTrace();    }   }   total = total + s.getNumber();   this.notifyAll();  }  //从仓库拿出物品,数量为num  synchronized void takeOut(Something s, int num) {       if(total < num) {    System.out.println("仓库物品不足清等待");    try {     this.wait();    } catch (InterruptedException e) {     e.printStackTrace();    }   }   total = total - num;    this.notifyAll();  }    /*   * 获得仓库的相关信息   */  int getID() {   return id;  }  int getTotal() {   return total;  }  int getCapa city() {   return capacity;  }    void setTotal(int t) {   this.total = t;  } } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ package test; /* 生产者消费者问题--物品  * @author yeS  * @version 1.0.0  */ public class Something {    /*   * 物品的名字   * 物品的数量   */  private String name;  private int number;    //物品的无参构造函数(2009.12.12修改)  Something(String n) {   number = 0;   name = n;  }    //修改物品数量  void setNumber(int num) {   number = num;  }    /*   * 获得物品信息   */  int getNumber() {   return number;  }  String getNa me() {   return name;  }   } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //(2009.12.12修改) package test1;  /* 生产者消费者问题  * @author yeS  * @version 1.0.0  */ public class ProductorAndConsumer {  public static void main(String[] args) {      Warehouse w = new Warehouse(1,20);   Something s1 = new Something("西瓜");   Something s2 = new Something("苹果");   Productor p1 = new Productor(s1, 5, 3, w);   Productor p2 = new Productor(s2, 5, 3, w);   Consumer c1 = new Consumer(w, s1, 1, 15);   Consumer c2 = new Consumer(w,s2,1,15);   Thread t1 = new Thread(p1);   Thread t2 = new Thread(p2);   Thread t3 = new Thread(c1);   Thread t4 = new Thread(c2);      t1.start();   t2.start();   t3.start();   t4.start();  } } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 编写多线程Web 服务器 会编写单线程,多线程就不是问题.只需要注意哪段是要同步运行的代码即可   package ThreadedServer; /* 多线程的http1.0服务器  * @author yeS  * @version 1.0.0  */ import java.io.*; import java.net.*; import java.util.*; public class ThreadedServer {  public static final int PORT_3490 = 8000;  public static String DEFAULTPATH_3490 = "c:/www/";    public static void main(String[] args) {      //启动服务器   try {    ServerSocket serverSocket_3490 = new ServerSocket(PORT_3490);              System.out.println("*****************************");          System.out.println("  *****夜觞服务器已经启动*****  ");          System.out.println("  ****服务器端口号:  " + PORT_3490 + "****  ");          System.out.println("****************************");               while(true) {                     //建立连接     Socket clientSocket_3490 = serverSocket_3490.accept();          Server server = new Server(clientSocket_3490,DEFAULTPATH_3490);     Thread thread = new Thread(server);     thread.start();          }   } catch (IOException e) {    // TODO Auto-generated catch block    e.printStackTrace();   }  } } class Server implements Runnable {    private Socket clientSocket_3490;  private String DEFAULTPATH_3490;  Server(Socket socket_3490, String defaultPath_3490) {   clientSocket_3490 = socket_3490;   DEFAULTPATH_3490 = defaultPath_3490;  }    public void run() {      try {                  //声明从客户端读取数据要用的流     BufferedReader rFromClient_3490 = new BufferedReader(       new InputStreamReader(clientSocket_3490.getInputStream()));     //声明从服务器发送数据到客户端要用的流     DataOutputStream wToClient_3490 = new DataOutputStream(clientSocket_3490.getOutputStream());     PrintStream pToClient_3490 = new PrintStream(clientSocket_3490.getOutputStream());     //将从客户端读取的数据的一行赋值给messageFromClient_3490     String messageFromClient_3490 = rFromClient_3490.readLine();          /*      * 处理从客户端读取的消息      */     StringTokenizer token_3490 = new StringTokenizer(messageFromClient_3490);             System.out.println("客户端发送的请求报文:" + messageFromClient_3490);        // 读取客户端发送过来的请求报文头部信息        while((messageFromClient_3490 = rFromClient_3490.readLine()) != null) {                  System.out.println(messageFromClient_3490);            if(messageFromClient_3490.equals(""))            break;        }          //处理get请求     if(token_3490.nextToken().equalsIgnoreCase("get")) {      //获得文件路径      String filePath_3490 = token_3490.nextToken();      if(filePath_3490.startsWith("/") == true) {       filePath_3490 = DEFAULTPATH_3490 + filePath_3490.substring(1);      } else {       System.out.println("请输入正确的命令(get /文件名)");       return ;      }      //将文件的内容写入字节数组中      File file_3490 = new File(filePath_3490);      int fileLength_3490 = (int)file_3490.length();      byte[] bufForFile_3490 = new byte[fileLength_3490];      FileInputStream rFromFile_3490 = new FileInputStream(filePath_3490);      rFromFile_3490.read(bufForFile_3490);           /*       * 发送数据到客户端       */      //响应报文格式      wToClient_3490.writeBytes("HTTP/1.0 200 OK\n");      wToClient_3490.writeBytes("Date: " + new Date().toGMTString() + "\n");      wToClient_3490.wri teBytes("Server: yeS Server/1.0.0\n");      wToClient_3490.writeBytes("Content-Length: " + fileLength_3490 + "\n");      if(filePath_3490.endsWith(".html")||filePath_3490.endsWith(".htm"))       wToClient_3490.writeBytes("Conten-Type: text/html\r\n");      if(filePath_3490.endsWith(".jsp"))       wToClient_3490.writeBytes("Conten-Type: text/jsp\r\n");      if(filePath_3490.endsWith(".jpg"))       wToClient_3490.writeBytes("Conten-Type: image/jpg\r\n");      if(filePath_3490.endsWith(".gif"))       wToClient_3490.writeBytes("Conten-Type: image/gif\r\n");      wToClient_3490.writeBytes("\r\n");      wToClient_3490.flush();            //向客户端传送文件      pToClient_3490.write(bufForFile_3490, 0, bufForFile_3490.length);      pToClient_3490.flush();      pToClient_3490.close();            clientSocket_3490.close();           }       } catch (IOException e) {    // TODO Auto-generated catch block    e.printStackTrace();   }     } } 简单的HTTP 1.0 客户端/服务器程序 基本实现,但是客户端只能保存小于16k的图片,不知道为什么.有会的请告诉我下,谢谢.我自己也会继续探求解决之法的. ~~~~~~~~~~~~~~~~~~~服务器~~~~~~~~~~~~~~~~~~~~~~~~~~~ package http; /* http1.0服务器  * @author yeS  * @version 1.0.0  */ import java.io.*; import java.net.*; import java.util.*; public class Server {  public static final int PORT_3490 = 8000;  public static String DEFAULTPATH_3490 = "c:/www/";    @SuppressWarnings("deprecation")  public static void main(String[] args) {      try {    //启动服务器    ServerSocket serverSocket_3490 = new ServerSocket(PORT_3490);          System.out.println("*****************************");          System.out.println("  *****夜觞服务器已经启动*****  ");          System.out.println("  ****服务器端口号:  " + PORT_3490 + "****  ");          System.out.println("****************************");                      while(true) {           //建立连接     Socket clientSocket_3490 = serverSocket_3490.accept();          //声明从客户端读取数据要用的流     BufferedReader rFromClient_3490 = new BufferedReader(       new InputStreamReader(clientSocket_3490.getInputStream()));     //声明从服务器发送数据到客户端要用的流     DataOutputStream wToClient_3490 = new DataOutputStream(clientSocket_3490.getOutputStream());     PrintStream pToClient_3490 = new PrintStream(clientSocket_3490.getOutputStream());     //将从客户端读取的数据的一行赋值给messageFromClient_3490     String messageFromClient_3490 = rFromClient_3490.readLine();          /*      * 处理从客户端发送过来的请求报文      */     StringTokenizer token_3490 = new StringTokenizer(messageFromClient_3490);             System.out.println("客户端发送的请求报文:" + messageFromClient_3490);        // 读取客户端发送过来的请求报文头部信息        System.out.println(messageFromClient_3490);                 //处理get请求     if(token_3490.nextToken().equalsIgnoreCase("get")) {      //获得文件路径      String filePath_3490 = token_3490.nextToken();      if(filePath_3490.startsWith("/") == true) {       filePath_3490 = DEFAULTPATH_3490 + filePath_3490.substring(1);      }      //将文件的内容写入字节数组中      File file_3490 = new File(filePath_3490);      int fileLength_3490 = (int)file_3490.length();      byte[] bufForFile_3490 = new byte[fileLength_3490];      FileInputStream rFromFile_3490 = new FileInputStream(filePath_3490);      rFromFile_3490.read(bufForFile_3490);           /*       * 发送数据到客户端       */      //响应报文格式      wToClient_3490.writeBytes("HTTP/1.0 200 OK\n");      wToClient_3490.writeBytes("Date: " + new Date().toGMTString() + "\n");      wToClient_3490.writeBytes("Server: yeS Server/ 1.0.0\n");      wToClient_3490.writeBytes("Content-Length: " + fileLength_3490 + "\n");      if(filePath_3490.endsWith(".html")||filePath_3490.endsWith(".htm"))       wToClient_3490.writeBytes("Conten-Type: text/html\r\n");      if(filePath_3490.endsWith(".jsp"))       wToClient_3490.writeBytes("Conten-Type: text/jsp\r\n");      if(filePath_3490.endsWith(".jpg"))       wToClient_3490.writeBytes("Conten-Type: image/jpg\r\n");      if(filePath_3490.endsWith(".gif"))       wToClient_3490.writeBytes("Conten-Type: image/gif\r\n");      wToClient_3490.writeBytes("\r\n");      wToClient_3490.flush();            //向客户端传送文件      pToClient_3490.write(bufForFile_3490, 0, bufForFile_3490.length);      pToClient_3490.flush();      pToClient_3490.close();            clientSocket_3490.close();           }          }       } catch (IOException e) {    // TODO Auto-generated catch block    e.printStackTrace();   }  } } ~~~~~~~~~~~~~~~~~~~~~客户端~~~~~~~~~~~~~~~~~~~~~~~~ package http; /* http1.0客户端  * @author yeS  * @version 1.0.0  */ import java.io.*; import java.net.*; public class Client {  public static final String HOST_3490 = "localhost";  public static final int SERVERPORT_3490 = 8000;    public static void main(String[] args) {      try {    //和服务器建立连接    Socket clientSocket_3490 = new Socket(HOST_3490,SERVERPORT_3490);    System.out.println("与服务器的连接已经建立");    System.out.println("请输入您要向服务端发送的请求");    System.out.println("(请求格式: GET /文件名. ps: 默认路径是C:/www/; 或者GET 文件全路径)");    //声明传送和接收数据用到的流    BufferedReader rFromIn_3490 = new BufferedReader(      new InputStreamReader(System.in));    InputStream rFromServer_3490 = new BufferedInputStream(clientSocket_3490.getInputStream());        /*     * 将命令发送给服务器     */    PrintStream wToServer_3490 = new PrintStream(clientSocket_3490.getOutputStream());    String messageFronIn_3490 = rFromIn_3490.readLine();    wToServer_3490.println(messageFronIn_3490);    /*     * 读取服务器响应的信息     */    boolean isHead_3490 = false;    String headMessage_3490 = "";    int messageFromServer_3490 = rFromServer_3490.read();    headMessage_3490 += (char)messageFromServer_3490;    // 判断读到的的字符串是否为 "\r\n\r\n", 如果是,则已经得到完整的head,将isHead_3490置为true,结束while循环    while (messageFromServer_3490 != -1 && !isHead_3490) {     switch (messageFromServer_3490) {     case 13:      messageFromServer_3490 = rFromServer_3490.read();      switch (messageFromServer_3490) {      case 10:       headMessage_3490 += (char) messageFromServer_3490;       if ((char) (messageFromServer_3490 = rFromServer_3490.read()) == ('\r'))        if ((char) (messageFromServer_3490 = rFromServer_3490.read()) == ('\n'))         isHead_3490 = true;       break;      default:       break;      }      break;     default:      break;     }     if (isHead_3490)      break;     messageFromServer_3490 = rFromServer_3490.read();          headMessage_3490 += (char) messageFromServer_3490;    }    System.out.println("服务端的响应报文:\n" + headMessage_3490 + "\n");    /*     * 保存文件     */    int fileLength_3490 = rFromServer_3490.available();    byte[] bufForFile_3490 = new byte[fileLength_3490];    rFromServer_3490.read(bufForFile_3490, 0, bufForFile_3490.length);        System.out.println("请输入您要保存的文件的名字: ");    String fileName_3490 = rFromIn_3490.readLine();    FileOutputStream wToFile_3490 = new FileOutputStream(fileName_3490);    wToFile_3490.write(bufForFile_3490);    wToFile_3490.flush();    wToFile_3490.close();    System.out.println("文件已保存!");        clientSocket_3490.close();       } catch (UnknownHostException e) {    // TODO Auto-generated catch block    e.printStackTrace();   } catch (IOException e) {    // TODO Auto-generated catch block    e.printStackTrace();   }     } } 基于TCP的聊天程序 ~~~~~~~~~~~~~~~~~~~~服务端~~~~~~~~~~~~~~~~~~~~~~~ package network; /* Java学习之网络编程_TCPServer  * @author yeS  * @version 1.0.0  */ import java.io.*; import java.net.*; public class TCPServer {  public static int PORT = 8002;  public static void main(String[] args) {      String readline = null;   try {    //开启服务器    ServerSocket ss = new ServerSocket(PORT);    System.out.println("服务器已启动");    //等待来自客户端的连接    Socket sc = ss.accept();    /*     * 定义     * 从键盘读取的流: rFormIn     * 从客户端读取的流: rFromClient     * 输出流: pwToClient     */    BufferedReader rFromIn = new BufferedReader(      new InputStreamReader(System.in));    BufferedReader rFromClient = new BufferedReader(      new InputStreamReader(sc.getInputStream()));    PrintWriter pwToClient = new PrintWriter(sc.getOutputStream());        //将从客户端传来的数据打印出来    System.out.println("Client: " + rFromClient.readLine());    //将服务器从键盘输入的数据作为字符串赋值给readline    readline = rFromIn.readLine();    //当输入的数据不是exit的时候,进入循环    while(!readline.equalsIgnoreCase("exit")) {     //输出服务端从键盘输入的内容     System.out.println("Server: " + readline);     //并将内容发送到客户端     pwToClient.println(readline);     pwToClient.flush();     //打印客户端传来的数据     System.out.println("Client: " + rFromClient.readLine());     //再将服务器从键盘输入的数据作为字符串赋值给readline     readline = rFromIn.readLine();    }    rFromClient.close();    pwToClient.close();    sc.close();    ss.close();   } catch (IOException e) {    // TODO Auto-generated catch block    e.printStackTrace();   }  } } ~~~~~~~~~~~~~~~~~~~~客户端~~~~~~~~~~~~~~~~~~~~~~~ package network; /* Java学习之网络编程_TCPClient  * @author yeS  * @version 1.0.0  */ import java.io.*; import java.net.*; public class TCPClient {  public static void main(String[] args) {      String readline = null;   try {    //和服务端建立连接    Socket ss = new Socket("localhost",8002);    System.out.println("已经和" + ss.getInetAddress() + "建立连接,现在你们可以通话了");    /*     * 定义     * 从键盘读取数据的流: rFromIn     * 从服务端读取数据的流: rFromServer     * 传送到服务端的流: pwToServer     */    BufferedReader rFromIn = new BufferedReader(      new InputStreamReader(System.in));    BufferedReader rFromServer = new BufferedReader(      new InputStreamReader(ss.getInputStream()));    PrintWriter pwToServer = new PrintWriter(ss.getOutputStream());    //从键盘读取数据,将数据转换成字符串赋值给readline    readline = rFromIn.readLine();    //如果从键盘输入的数据不是exit则进入循环    while(!readline.equalsIgnoreCase("exit")) {     //打印客户端从键盘输入的内容     System.out.println("Client: " + readline);     //并将内容传给服务端     pwToServer.println(readline);     pwToServer.flush();     //输出从服务端传来的数据     System.out.println("Server: " + rFromServer.readLine());     //从键盘读取数据,将数据转换成字符串赋值给readline     readline = rFromIn.readLine();    }    rFromServer.close();    pwToServer.close();    ss.close();   } catch (UnknownHostException e) {    // TODO Auto-generated catch block    e.printStackTrace();   } catch (IOException e) {    // TODO Auto-generated catch block    e.printStackTrace();   }  } }

下载文档到电脑,查找使用更方便

文档的实际排版效果,会与网站的显示效果略有不同!!

需要 5 金币 [ 分享文档获得金币 ] 0 人已下载

下载文档