会员可以在此提问,百战程序员老师有问必答
对大家有帮助的问答会被标记为“推荐”
看完课程过来浏览一下别人提的问题,会帮你学得更全面
截止目前,同学们一共提了 133810个问题
JAVA 全系列/第二阶段:JAVA 基础深化和提高/网络编程 3856楼
JAVA 全系列/第二阶段:JAVA 基础深化和提高/多线程技术(旧) 3858楼

截屏2021-09-03 下午3.51.45.png

同楼上,一样的报错,不知原因


JAVA 全系列/第二阶段:JAVA 基础深化和提高/IO 流技术(旧) 3859楼

老师我这里为何会报异常,请老师帮忙看看谢谢,学到这,我有点迷糊了,有点听不懂了

package com.bjsxt.server;
import java.util.List;
import java.util.Map;
import org.dom4j.Element;
import com.bjsxt.servelet.Servlet;
/**
 * 编写WebApp类
 * @author ADMIN
 *(1)初始化程序运行的数据
 *(2)根据不同的url创建所请求的Servlet对象
 */
public class WebApp {//App的意思就是应用程序
 private static ServletContext contxt;
 //使用静态块初始化Servlet容器
 static{
  contxt=new ServletContext();
  //分别获取对应关系的Map集合
  Map<String,String>servlet=contxt.getServlet();
  Map<String,String>mapping=contxt.getMapping();
  //创建解析XML文件的对象
  webDom4j web=new webDom4j();
  web.parse(web.getDocument());//解析xml
  //获取解析XML之后的List集合
  List<Entity>entityList=web.getEntityList();
  List<Mapping>mappingList=web.getMappingList();
 
  //将List集合中的数据存储到Map集合中去
  for (Entity entity : entityList) {
   servlet.put(entity.getName(), entity.getClazz());
  }
  //System.out.println(servlet);
  for(Mapping map:mappingList){
   //遍历url-pattern的集合
   List<String>urlPattern=map.getUrlPattern();
   for(String s:urlPattern ){
    mapping.put(s, map.getName());
   }
  
  } 
  //System.out.println(mapping);
 }
 /**
  * 根据url创建不同的Servlet对象
  * @param url
  * @return
  */
 public static Servlet getServlet(String url){
  if(url==null||url.trim().equals("")){
   return null;
  }
  //调用无参构造方法创建Servlet对象
  
  try {
   //如果url正确
   //根据url的key获取Servlet -name的值/log=login, /reg=register
   String servletName=contxt.getMapping().get(url);
   //根据servletName得到对应的servlet-class
   String servletClass=contxt.getServlet().get(servletName);//得到的是一个完整的包名+类名的字符串
   //使用反射创建Servlet对象
   Class<?>clazz=Class.forName(servletClass);
   Servlet servlet = (Servlet) clazz.newInstance();
   return servlet;
  } catch (ClassNotFoundException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (InstantiationException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (IllegalAccessException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
  return null;
 }
 public static void main(String[] args) {
  System.out.println(getServlet("/log"));
 }
}

image.png

JAVA 全系列/第二阶段:JAVA 基础深化和提高/手写服务器项目(旧) 3865楼
JAVA 全系列/第二阶段:JAVA 基础深化和提高/容器 3866楼

class ManTou {
    private int id;

    public ManTou(int id) {
        this.id = id;
    }

    public int getId() {
        return this.id;
    }
}

/**
 * 定义缓冲区类
 */
class SyncStack {
    //定义存放馒头的盒子
    private ManTou[] manTous = new ManTou[10];
    //定义操作盒子的索引
    private int index;

    /**
     * 放馒头的方法
     */

    public synchronized void put(ManTou manTou) {
        //判断盒子是否已满
        while (this.index == this.manTous.length) {
            try {
                this.wait();    //wait()必须在synchronized块中调用  wait()执行后 线程会将持有的对象锁释放 并进入阻塞状态 其他需要该对象锁的线程就可以继续运行了
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        //唤醒取馒头的线程
        this.notify();      //该方法必须在synchronized块中调用 会唤醒处于等待状态队列中的一个线程
        this.manTous[this.index] = manTou;
        this.index++;
    }

    /**
     * 取馒头的方法
     */
    public synchronized ManTou get() {
        //判断盒子是否已空
        while (this.index == 0) {
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        this.notify();
        this.index--;
        return this.manTous[this.index];
    }
}

/**
 * 定义生产者线程类
 */
class ShengChan extends Thread {
    private SyncStack syncStack;

    public ShengChan(SyncStack syncStack) {
        this.syncStack = syncStack;
    }
    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            ManTou manTou = new ManTou(i);
            syncStack.put(manTou);
            System.out.println("生产第"+(i+1)+"个馒头");
        }
    }
}

/**
 * 定义消费者线程类
 */
class Xiaofei extends Thread {
    private SyncStack syncStack;

    public Xiaofei(SyncStack syncStack) {
        this.syncStack = syncStack;
    }
    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            ManTou manTou = this.syncStack.get();
            System.out.println("消费了" + (i+1) + "个馒头");

        }
    }
}

public class ProduceThread {
    public static void main(String[] args) {
        SyncStack syncStack = new SyncStack();
        new ShengChan(syncStack).start();
        new Xiaofei(syncStack).start();
    }
}

image.png

image.png

image.png

image.png

老师为什么我这里会出现先消费的现象啊? 

JAVA 全系列/第二阶段:JAVA 基础深化和提高/多线程技术(旧) 3867楼
JAVA 全系列/第二阶段:JAVA 基础深化和提高/网络编程(旧) 3869楼

课程分类

百战程序员微信公众号

百战程序员微信小程序

©2014-2025百战汇智(北京)科技有限公司 All Rights Reserved 北京亦庄经济开发区科创十四街 赛蒂国际工业园
网站维护:百战汇智(北京)科技有限公司
京公网安备 11011402011233号    京ICP备18060230号-3    营业执照    经营许可证:京B2-20212637