- 浏览: 55604 次
- 性别:
- 来自: 杭州
最新评论
实现招生录取系统中的部分功能(使用main方法作为程序入口) 1. 读XML文件,进过程序处理后,总成绩按降序排序,结果通过IO流输出到result_1.txt文件中。如: 班级[className classID] 学员姓名 学员ID[总分:457,学科ID:87,学科ID:83,学科ID:82,学科ID:83] 学员姓名 学员ID[总分:453,学科ID:87,学科ID:83,学科ID:82,学科ID:83] 学员姓名 学员ID[总分:448,学科ID:87,学科ID:83,学科ID:82,学科ID:83] 班级[className classID] 学员姓名 学员ID[总分:457,学科ID:87,学科ID:83,学科ID:82,学科ID:83] 学员姓名 学员ID[总分:454,学科ID:87,学科ID:83,学科ID:82,学科ID:83] 学员姓名 学员ID[总分:445,学科ID:87,学科ID:83,学科ID:82,学科ID:83] 说明: className classID用空格隔开,className为班级名称,classID为班级编号。 学员姓名 学员ID用空格隔开,每位学员成绩独占一行。总分为学员各学科成绩之和。 2. 通过IO读result_1.txt文件,以多线程方式实现大学录取学生功能 大学列表:清华大学、北京大学、南京大学、复旦大学、南京职业技术学院 说明: A类大学为清华大学、北京大学,分数线为340,名额各为3名,; B类大学为南京大学、复旦大学,分数线为320,名额各为10名;; C类大学为南京职业技术学院,分数线为250,名额不限; 分数超过名额应该取最高分;达不到分数线可以不录取; 录取按大学类别进行:先A类,再B类,最后C类; 同类大学之间可以抢学生,同一学生只能被一所大学录取,以先录取为准; 结果通过IO输出result_2.txt,如: 清华大学: 学员姓名 学员ID[总分:457,学科ID:87,学科ID:83,学科ID:82,学科ID:83] 北京大学:学员姓名 学员ID[总分:448,学科ID:87,学科ID:83,学科ID:82,学科ID:83] 南京大学:学员姓名 学员ID[总分:448,学科ID:87,学科ID:83,学科ID:82,学科ID:83] 复旦大学:学员姓名 学员ID[总分:448,学科ID:87,学科ID:83,学科ID:82,学科ID:83] 南京职业技术学院:学员姓名 学员ID[总分:448,学科ID:87,学科ID:83,学科ID:82,学科ID:83] 未被录取学员: 学员姓名 学员ID[总分:128],学员姓名 学员ID[总分:215] xml文档如下: <root> <!--表结构--> <tables> <!--学员表--> <table id="1000" name="studentTbl"> <fields> <field id="studentId" /><!--学号--> <field id="name" /><!--姓名--> <field id="sex "/><!--性别--> </fields> </table> <!--班级表--> <table id="1001" name="classTbl"> <fields> <field id="classId" /><!--班级编号--> <field id="name" /><!--班级名称--> </fields> </table> <!--班级学员表--> <table id="1004" name="classStudentTbl"> <fields> <field id="classId" /><!--班级编号--> <field id="studentId" /><!--学号--> </fields> </table> <!--学科表--> <table id="1002" name="subjectTbl"> <fields> <field id="subjectId" /><!--学科编号--> <field id="name" /><!--学科名称--> </fields> </table> <!--成绩表--> <table id="1003" name="scoreTbl"> <fields> <field id="studentId" /><!--学号--> <field id="subjectId" /><!--学科编号--> <field id="score" /><!--成绩--> </fields> </table> </tables> <!--数据信息,字段值以','分隔--> <datas> <!--学员数据--> <data tableid="1000"> <fields-data>st001,张一,男</fields-data> <fields-data>st002,李二,男</fields-data> <fields-data>st003,王三,女</fields-data> <fields-data>st004,杨四,男</fields-data> <fields-data>st005,赵五,男</fields-data> <fields-data>st006,郑陆,女</fields-data> <fields-data>st007,林世,男</fields-data> <fields-data>st008,胡长,男</fields-data> <fields-data>st009,邹家,男</fields-data> <fields-data>st010,李方,男</fields-data> <fields-data>st011,宁可,男</fields-data> <fields-data>st012,张杂,男</fields-data> <fields-data>st013,李度,男</fields-data> <fields-data>st014,王等,女</fields-data> <fields-data>st015,杨角,男</fields-data> <fields-data>st016,赵度,男</fields-data> <fields-data>st017,郑来,男</fields-data> <fields-data>st018,林衡,男</fields-data> <fields-data>st019,胡量,男</fields-data> <fields-data>st020,邹代,女</fields-data> <fields-data>st021,李码,男</fields-data> <fields-data>st022,宁的,男</fields-data> <fields-data>st023,张质,男</fields-data> </data> <!--班级数据--> <data tableid="1001"> <fields-data>1,一年级</fields-data> <fields-data>2,二年级</fields-data> <fields-data>3,三年级</fields-data> </data> <!--学员班级信息--> <data tableid="1004"> <fields-data>1,st001</fields-data> <fields-data>2,st002</fields-data> <fields-data>3,st003</fields-data> <fields-data>1,st004</fields-data> <fields-data>2,st005</fields-data> <fields-data>3,st006</fields-data> <fields-data>1,st007</fields-data> <fields-data>2,st008</fields-data> <fields-data>3,st009</fields-data> <fields-data>2,st010</fields-data> <fields-data>3,st011</fields-data> <fields-data>3,st012</fields-data> <fields-data>1,st013</fields-data> <fields-data>1,st014</fields-data> <fields-data>2,st015</fields-data> <fields-data>3,st016</fields-data> <fields-data>3,st017</fields-data> <fields-data>2,st018</fields-data> <fields-data>1,st019</fields-data> <fields-data>1,st020</fields-data> <fields-data>2,st021</fields-data> <fields-data>3,st022</fields-data> <fields-data>2,st023</fields-data> <fields-data>3,st024</fields-data> </data> <!--学科数据--> <data tableid="1002"> <fields-data>1,英语</fields-data> <fields-data>2,化学</fields-data> <fields-data>3,代数</fields-data> <fields-data>4,计算机</fields-data> </data> <!--成绩数据--> <data tableid="1003"> <fields-data>st001,1,80</fields-data> <fields-data>st001,2,90</fields-data> <fields-data>st001,3,70</fields-data> <fields-data>st001,4,100</fields-data> <fields-data>st002,1,77</fields-data> <fields-data>st002,2,88</fields-data> <fields-data>st002,3,99</fields-data> <fields-data>st002,4,56</fields-data> <fields-data>st003,1,96</fields-data> <fields-data>st003,2,56</fields-data> <fields-data>st003,3,88</fields-data> <fields-data>st003,4,69</fields-data> <fields-data>st004,1,78</fields-data> <fields-data>st004,2,85</fields-data> <fields-data>st004,3,83</fields-data> <fields-data>st004,4,96</fields-data> <fields-data>st005,1,79</fields-data> <fields-data>st005,2,87</fields-data> <fields-data>st005,3,91</fields-data> <fields-data>st005,4,85</fields-data> <fields-data>st006,1,79</fields-data> <fields-data>st006,2,87</fields-data> <fields-data>st006,3,68</fields-data> <fields-data>st006,4,86</fields-data> <fields-data>st007,1,55</fields-data> <fields-data>st007,2,78</fields-data> <fields-data>st007,3,90</fields-data> <fields-data>st007,4,68</fields-data> <fields-data>st008,1,69</fields-data> <fields-data>st008,2,86</fields-data> <fields-data>st008,3,75</fields-data> <fields-data>st008,4,69</fields-data> <fields-data>st009,1,84</fields-data> <fields-data>st009,2,69</fields-data> <fields-data>st009,3,90</fields-data> <fields-data>st009,4,49</fields-data> <fields-data>st010,1,77</fields-data> <fields-data>st010,2,86</fields-data> <fields-data>st010,3,99</fields-data> <fields-data>st010,4,82</fields-data> <fields-data>st011,1,67</fields-data> <fields-data>st011,2,87</fields-data> <fields-data>st011,3,69</fields-data> <fields-data>st011,4,56</fields-data> <fields-data>st012,1,44</fields-data> <fields-data>st012,2,66</fields-data> <fields-data>st012,3,99</fields-data> <fields-data>st012,4,89</fields-data> <fields-data>st013,1,67</fields-data> <fields-data>st013,2,87</fields-data> <fields-data>st013,3,78</fields-data> <fields-data>st013,4,78</fields-data> <fields-data>st014,1,56</fields-data> <fields-data>st014,2,78</fields-data> <fields-data>st014,3,88</fields-data> <fields-data>st014,4,11</fields-data> <fields-data>st015,1,0</fields-data> <fields-data>st015,2,44</fields-data> <fields-data>st015,3,66</fields-data> <fields-data>st015,4,99</fields-data> <fields-data>st016,1,67</fields-data> <fields-data>st016,2,98</fields-data> <fields-data>st016,3,78</fields-data> <fields-data>st016,4,99</fields-data> <fields-data>st017,1,89</fields-data> <fields-data>st017,2,88</fields-data> <fields-data>st017,3,90</fields-data> <fields-data>st017,4,96</fields-data> <fields-data>st018,1,93</fields-data> <fields-data>st018,2,95</fields-data> <fields-data>st018,3,96</fields-data> <fields-data>st018,4,91</fields-data> <fields-data>st019,1,98</fields-data> <fields-data>st019,2,94</fields-data> <fields-data>st019,3,93</fields-data> <fields-data>st019,4,89</fields-data> <fields-data>st020,1,87</fields-data> <fields-data>st020,2,96</fields-data> <fields-data>st020,3,79</fields-data> <fields-data>st020,4,82</fields-data> <fields-data>st021,1,77</fields-data> <fields-data>st021,2,87</fields-data> <fields-data>st021,3,89</fields-data> <fields-data>st021,4,86</fields-data> <fields-data>st022,1,94</fields-data> <fields-data>st022,2,76</fields-data> <fields-data>st022,3,69</fields-data> <fields-data>st022,4,79</fields-data> <fields-data>st023,1,87</fields-data> <fields-data>st023,2,57</fields-data> <fields-data>st023,3,48</fields-data> <fields-data>st023,4,48</fields-data> <fields-data>st024,1,56</fields-data> <fields-data>st024,2,68</fields-data> <fields-data>st024,3,78</fields-data> <fields-data>st024,4,81</fields-data> <fields-data>st025,1,99</fields-data> <fields-data>st025,2,47</fields-data> <fields-data>st025,3,68</fields-data> <fields-data>st025,4,98</fields-data> <fields-data>st026,1,69</fields-data> <fields-data>st026,2,95</fields-data> <fields-data>st026,3,75</fields-data> <fields-data>st026,4,95</fields-data> <fields-data>st027,1,84</fields-data> <fields-data>st027,2,85</fields-data> <fields-data>st027,3,96</fields-data> <fields-data>st027,4,76</fields-data> <fields-data>st028,1,83</fields-data> <fields-data>st028,2,95</fields-data> </data> </datas> </root>
实现:
import java.util.Set; import java.util.TreeSet; /** * 班级类 */ public class Class implements Comparable<Class> { private int classId; private String name; //维护本班级下面所有的student private Set<Student> students; public Class() { //有序存储student对象 students = new TreeSet<Student>(); } public Class(int classId, String name) { this(); this.classId = classId; this.name = name; } public void setStudents(Set<Student> students) { this.students = students; } public Set<Student> getStudents() { return students; } public int getClassId() { return classId; } public void setClassId(int classId) { this.classId = classId; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "班级[" + name + " " + classId + "]"; } @Override public int compareTo(Class o) { return classId - o.classId; } }
import java.util.Set; import java.util.TreeSet; /** * 学生类 */ public class Student implements Comparable<Student> { private String studentId; private String name; private String sex; private Set<Score> scores; public Student() { scores = new TreeSet<Score>(); } public Student(String studentId, String name, String sex) { this(); this.studentId = studentId; this.name = name; this.sex = sex; } public Set<Score> getScores() { return scores; } public void setScores(Set<Score> scores) { this.scores = scores; } public String getStudentId() { return studentId; } public void setStudentId(String studentId) { this.studentId = studentId; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } //按总成绩对学生排序,如果总成绩相同,按学号排序 @Override public int compareTo(Student o) { float total = 0f; for (Score score : scores) total += score.getScore(); float o_total = 0f; for (Score score : o.getScores()) o_total += score.getScore(); int result = (int) (o_total - total); if (result != 0) return result; return studentId.compareTo(o.studentId); } @Override public String toString() { StringBuilder result = new StringBuilder(); result.append(name).append(' ').append(studentId).append("[总分:%3d, "); float total = 0f; for (Score score : scores) { result.append(score.getCourse().getName()).append(":").append(String.format("%3d", (int) score.getScore())) .append(", "); total += score.getScore(); } return String.format(result.substring(0, result.length() - 2) + "]", (int) total); } }
/** * 成绩类 */ public class Score implements Comparable<Score> { private float score; private Student student; private Course course; public Score(float score, Student student, Course course) { this.score = score; this.student = student; this.course = course; } public Score() { } public float getScore() { return score; } public void setScore(float score) { this.score = score; } public Student getStudent() { return student; } public void setStudent(Student student) { this.student = student; } public Course getCourse() { return course; } public void setCourse(Course course) { this.course = course; } //按课程号进行排序 @Override public int compareTo(Score o) { return course.getSujectId() - o.course.getSujectId(); } }
/** * 课程类 */ public class Course { private int sujectId; private String name; public Course() { } public Course(int sujectId, String name) { this.sujectId = sujectId; this.name = name; } public int getSujectId() { return sujectId; } public void setSujectId(int sujectId) { this.sujectId = sujectId; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
import java.io.IOException; import java.util.HashMap; import java.util.Set; import java.util.TreeSet; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; /** * * 解析xml文档的工具类 */ public class DataParser { //定义解析数据过程中需要用到的一些常量数据 private static final String DATA_ELEMENT = "data"; private static final String FIELD_DATA_ELEMENT = "fields-data"; private static final String TABLE_ID_ATTRIBUTE = "tableid"; private static final String STUDENT_DATA = "1000"; private static final String CLASS_DATA = "1001"; private static final String COURSE_DATA = "1002"; private static final String SCORE_DATA = "1003"; private static final String STUDENT_CLASS_DATA = "1004"; public static void main(String[] args) { Set<Class> classes = getClasses("src/data.xml"); PrintWriter writer = new PrintWriter(new OutputStreamWriter(new FileOutputStream("result_1.txt"), "UTF-8"), true); for (Class cls : classes) { writer.println(cls); for (Student student : cls.getStudents()) { writer.println(student); } } writer.close(); } public static Set<Class> getClasses(String filePath) { DocumentBuilderFactory parserFactory = DocumentBuilderFactory.newInstance(); //解析完成的数据 暂时存储在map集合中 方便查找 HashMap<Integer, Class> cls_map = new HashMap<Integer, Class>(); HashMap<String, Student> stu_map = new HashMap<String, Student>(); HashMap<Integer, Course> cour_map = new HashMap<Integer, Course>(); try { DocumentBuilder parser = parserFactory.newDocumentBuilder(); Document doc = parser.parse(filePath); XPath xpath = XPathFactory.newInstance().newXPath(); //xpath表达式 %s表示待替换的属性值 String expr = "//" + DATA_ELEMENT + "[@" + TABLE_ID_ATTRIBUTE + "=%s]"; //解析class数据 Element cls_elt = (Element) xpath.compile(String.format(expr, CLASS_DATA)).evaluate(doc, XPathConstants.NODE); NodeList cls_items = cls_elt.getElementsByTagName(FIELD_DATA_ELEMENT); for (int i = 0; i < cls_items.getLength(); i++) { String item = cls_items.item(i).getTextContent(); String[] parts = item.split(","); if (parts.length != 2) throw new IllegalArgumentException("invalid class data item: " + item); int classId = Integer.parseInt(parts[0].trim()); String name = parts[1].trim(); cls_map.put(classId, new Class(classId, name)); } //解析student数据 Element stu_elt = (Element) xpath.compile(String.format(expr, STUDENT_DATA)).evaluate(doc, XPathConstants.NODE); NodeList stu_items = stu_elt.getElementsByTagName(FIELD_DATA_ELEMENT); for (int i = 0; i < stu_items.getLength(); i++) { String item = stu_items.item(i).getTextContent(); String[] parts = item.split(","); if (parts.length != 3) throw new IllegalArgumentException("invalid student data item: " + item); String studentId = parts[0].trim(); String name = parts[1].trim(); String sex = parts[2].trim(); stu_map.put(studentId, new Student(studentId, name, sex)); } //解析course数据 Element cour_elt = (Element) xpath.compile(String.format(expr, COURSE_DATA)).evaluate(doc, XPathConstants.NODE); NodeList cour_items = cour_elt.getElementsByTagName(FIELD_DATA_ELEMENT); for (int i = 0; i < cour_items.getLength(); i++) { String item = cour_items.item(i).getTextContent(); String[] parts = item.split(","); if (parts.length != 2) throw new IllegalArgumentException("invalid course data item: " + item); int courseId = Integer.parseInt(parts[0].trim()); String name = parts[1].trim(); cour_map.put(courseId, new Course(courseId, name)); } //解析score数据 Element score_elt = (Element) xpath.compile(String.format(expr, SCORE_DATA)).evaluate(doc, XPathConstants.NODE); NodeList score_items = score_elt.getElementsByTagName(FIELD_DATA_ELEMENT); Score score; for (int i = 0; i < score_items.getLength(); i++) { String item = score_items.item(i).getTextContent(); String[] parts = item.split(","); if (parts.length != 3) throw new IllegalArgumentException("invalid score data item: " + item); String studentId = parts[0].trim(); Student stu = stu_map.get(studentId); if (stu == null) { System.out.println("invalid student id: " + studentId); continue; } int courseId = Integer.parseInt(parts[1].trim()); Course cour = cour_map.get(courseId); if (cour == null) { System.out.println("invalid course id: " + courseId); continue; } float grade = Float.parseFloat(parts[2].trim()); score = new Score(); score.setScore(grade); score.setCourse(cour); score.setStudent(stu); stu.getScores().add(score); } //解析class-student数据 Element stu_cls_elt = (Element) xpath.compile(String.format(expr, STUDENT_CLASS_DATA)).evaluate(doc, XPathConstants.NODE); NodeList stu_cls_items = stu_cls_elt.getElementsByTagName(FIELD_DATA_ELEMENT); for (int i = 0; i < stu_cls_items.getLength(); i++) { String item = stu_cls_items.item(i).getTextContent(); String[] parts = item.split(","); if (parts.length != 2) throw new IllegalArgumentException("invalid class to student mapping data item: " + item); int classId = Integer.parseInt(parts[0].trim()); String studentId = parts[1].trim(); Class cls = cls_map.get(classId); if (cls == null) { System.out.println("invalid class id: " + classId); continue; } Student stu = stu_map.get(studentId); if (stu == null) { System.out.println("invalid student id: " + studentId); continue; } cls.getStudents().add(stu); } } catch (ParserConfigurationException e) { throw new RuntimeException("parser configuration error", e); } catch (SAXException e) { throw new RuntimeException("parse error", e); } catch (IOException e) { throw new RuntimeException("io operation error", e); } catch (XPathExpressionException e) { throw new RuntimeException("xpath expression error", e); } //最终将class数据存储到treemap集合返回 return new TreeSet<Class>(cls_map.values()); } }
-------------------执行结果 result_1.txt-------------------------
班级[一年级 1] 胡量 st019[总分:374, 英语: 98, 化学: 94, 代数: 93, 计算机: 89] 邹代 st020[总分:344, 英语: 87, 化学: 96, 代数: 79, 计算机: 82] 杨四 st004[总分:342, 英语: 78, 化学: 85, 代数: 83, 计算机: 96] 张一 st001[总分:340, 英语: 80, 化学: 90, 代数: 70, 计算机:100] 李度 st013[总分:310, 英语: 67, 化学: 87, 代数: 78, 计算机: 78] 林世 st007[总分:291, 英语: 55, 化学: 78, 代数: 90, 计算机: 68] 王等 st014[总分:233, 英语: 56, 化学: 78, 代数: 88, 计算机: 11] 班级[二年级 2] 林衡 st018[总分:375, 英语: 93, 化学: 95, 代数: 96, 计算机: 91] 李方 st010[总分:344, 英语: 77, 化学: 86, 代数: 99, 计算机: 82] 赵五 st005[总分:342, 英语: 79, 化学: 87, 代数: 91, 计算机: 85] 李码 st021[总分:339, 英语: 77, 化学: 87, 代数: 89, 计算机: 86] 李二 st002[总分:320, 英语: 77, 化学: 88, 代数: 99, 计算机: 56] 胡长 st008[总分:299, 英语: 69, 化学: 86, 代数: 75, 计算机: 69] 张质 st023[总分:240, 英语: 87, 化学: 57, 代数: 48, 计算机: 48] 杨角 st015[总分:209, 英语: 0, 化学: 44, 代数: 66, 计算机: 99] 班级[三年级 3] 郑来 st017[总分:363, 英语: 89, 化学: 88, 代数: 90, 计算机: 96] 赵度 st016[总分:342, 英语: 67, 化学: 98, 代数: 78, 计算机: 99] 郑陆 st006[总分:320, 英语: 79, 化学: 87, 代数: 68, 计算机: 86] 宁的 st022[总分:318, 英语: 94, 化学: 76, 代数: 69, 计算机: 79] 王三 st003[总分:309, 英语: 96, 化学: 56, 代数: 88, 计算机: 69] 张杂 st012[总分:298, 英语: 44, 化学: 66, 代数: 99, 计算机: 89] 邹家 st009[总分:292, 英语: 84, 化学: 69, 代数: 90, 计算机: 49] 宁可 st011[总分:279, 英语: 67, 化学: 87, 代数: 69, 计算机: 56]
public class SelectStudent { //构建一个简单的Student类,存储从txt文件解析出来的Student对象 static class SimpleStudent implements Comparable<SimpleStudent> { //总成绩 private int score; //考生详细信息 private String info; public SimpleStudent() { } public SimpleStudent(int score, String info) { this.score = score; this.info = info; } public int getScore() { return score; } public void setScore(int score) { this.score = score; } public String getInfo() { return info; } public void setInfo(String info) { this.info = info; } //按总成绩排序,如果总成绩相同,按详细信息排序 @Override public int compareTo(SimpleStudent o) { int result = o.score - score; if (result != 0) return result; return info.compareTo(o.info); } @Override public String toString() { return info; } } private final Lock lock = new ReentrantLock(); //A类线程等待的信号 private final Condition con_a = lock.newCondition(); //B类线程等待的信号 private final Condition con_b = lock.newCondition(); //C类线程等待的信号 private final Condition con_c = lock.newCondition(); //使用一个线程池运行相关的Task private ExecutorService executor = Executors.newCachedThreadPool(); private int state = 0; public SelectStudent() { } public void shutdownExecutorNow() { if (!executor.isShutdown()) executor.shutdownNow(); } //线程管理类 abstract class Monitor implements Runnable { CountDownLatch cdl_before; CountDownLatch cdl_after; Monitor(CountDownLatch cdl_before, CountDownLatch cdl_after) { this.cdl_before = cdl_before; this.cdl_after = cdl_after; } @Override public void run() { //获得锁 lock.lock(); try { //具体实现由子类完成 process(); } catch (InterruptedException e) { throw new RuntimeException("interrupted error", e); } finally { //释放锁 lock.unlock(); } } abstract void process() throws InterruptedException; } //A类管理线程 class MonitorA extends Monitor { MonitorA(CountDownLatch cdl_before, CountDownLatch cdl_after) { super(cdl_before, cdl_after); } @Override void process() throws InterruptedException { //当state=0 表明当前状态允许执行 while (state % 3 != 0) //若条件不符合,在con_a条件上等待 con_a.await(); //通知A类线程开始执行 cdl_before.countDown(); //等待所有A类线程执行完成 cdl_after.await(); state++; //通知B类管理线程开始执行 con_b.signal(); } } //B类管理线程 class MonitorB extends Monitor { MonitorB(CountDownLatch cdl_before, CountDownLatch cdl_after) { super(cdl_before, cdl_after); } @Override void process() throws InterruptedException { //state=1 允许执行 while (state % 3 != 1) //若条件不符合,在con_b条件上等待 con_b.await(); //通知B类线程开始执行 cdl_before.countDown(); //等待所有B类线程执行完成 cdl_after.await(); state++; //通知C类管理线程开始执行 con_c.signal(); } } //C类管理线程 class MonitorC extends Monitor { MonitorC(CountDownLatch cdl_before, CountDownLatch cdl_after) { super(cdl_before, cdl_after); } @Override void process() throws InterruptedException { //state=2 运行执行 while (state % 3 != 2) //若条件不符合,在con_c条件上等待 con_c.await(); //通知所有C类线程执行 cdl_before.countDown(); } } //模拟TimeUnit.unit.sleep 非阻塞方法 void sleep(TimeUnit unit, long duration) { long startTime = System.nanoTime(); while (System.nanoTime() - startTime < unit.toNanos(duration)) { } } //录取考生线程(A类,B类,C类) class SelectTask implements Runnable { //学校名称 private String name; //录取人数 private int num; //分数线 private int grade; //考生列表 private List<SimpleStudent> students; //消息队列 private ConcurrentLinkedQueue<String> queue; //任务开始条件 private CountDownLatch cdl_before; //任务结束条件 private CountDownLatch cdl_after; SelectTask(String schoolName, List<SimpleStudent> stus, ConcurrentLinkedQueue<String> queue, int selectNum, int grade, CountDownLatch cdl_before, CountDownLatch cdl_after) { name = schoolName; students = stus; num = selectNum; this.grade = grade; this.queue = queue; this.cdl_before = cdl_before; this.cdl_after = cdl_after; } @Override public void run() { try { //等待任务开始条件 cdl_before.await(); SimpleStudent student; int i = 0; try { //开始录取操作 for (i = 0; i < num; i++) { sleep(TimeUnit.MILLISECONDS, 5); synchronized (students) { //如果学校列表已经为空,强制终止整个录取过程(强制关闭线程池) if (students.isEmpty()) { queue.offer(name + ": 没有可录取的学生!"); shutdownExecutorNow(); return; } student = students.get(0); //如果没有达到分数线,终止录取过程 if (student.getScore() < grade) break; //将录取信息加入到消息队列 queue.offer(name + ": " + students.remove(0).info); } } } finally { //将统计消息加入消息队列 //放在finally中,即使强制终止当前线程,也会执行该语句 queue.offer(name + ":[" + ((num == i || num == Integer.MAX_VALUE) ? "达标" : "未达标") + "] 当前录取" + i + "/总名额" + (num == Integer.MAX_VALUE ? "(无限制)" : num)); } } catch (InterruptedException e) { throw new RuntimeException("interrupted error", e); } finally { //当前任务运行结束 cdl_after.countDown(); } } } //打印未被录取考生信息的线程 class NotSelectTask implements Runnable { //考生列表 private List<SimpleStudent> students; //消息队列 private ConcurrentLinkedQueue<String> queue; //任务开始条件 private CountDownLatch cdl; public NotSelectTask(List<SimpleStudent> students, ConcurrentLinkedQueue<String> queue, CountDownLatch cdl) { this.students = students; this.queue = queue; this.cdl = cdl; } @Override public void run() { try { //等待任务开始条件(所有C类线程执行完毕) cdl.await(); while (!students.isEmpty()) //将未被录取考生信息加入消息队列 queue.offer("未被录取:" + students.remove(0).info); //终止线程池 executor.shutdown(); } catch (InterruptedException e) { throw new RuntimeException("wait interrupted", e); } } } //消息处理线程 从消息队列取出消息,通过输出流写到文件中 class OutputTask implements Runnable { private ConcurrentLinkedQueue<String> queue; private PrintWriter writer; OutputTask(ConcurrentLinkedQueue<String> queue, String outFile) { this.queue = queue; try { writer = new PrintWriter(new FileOutputStream(outFile)); } catch (FileNotFoundException e) { throw new RuntimeException(e); } } @Override public void run() { String content = null; while (true) { //如果录取线程池已经终止且当前消息队列为空,退出 if (executor.isTerminated() && queue.isEmpty()) break; content = queue.poll(); if (content != null) writer.println(content); writer.flush(); } writer.close(); } } public static void main(String[] args) throws Exception { SelectStudent ss = new SelectStudent(); List<SimpleStudent> stus = ss.parseTextFile("result_1.txt"); ss.select(stus); } public void select(List<SimpleStudent> list) { //消息队列 ConcurrentLinkedQueue<String> queue = new ConcurrentLinkedQueue<String>(); //构建消息处理线程 new Thread(new OutputTask(queue, "result_2.txt")).start(); CountDownLatch cdl_11 = new CountDownLatch(1); CountDownLatch cdl_21 = new CountDownLatch(2); //A类管理线程 executor.execute(new MonitorA(cdl_11, cdl_21)); //A类线程 executor.execute(new SelectTask("清华大学", list, queue, 3, 340, cdl_11, cdl_21)); //A类线程 executor.execute(new SelectTask("北京大学", list, queue, 3, 340, cdl_11, cdl_21)); CountDownLatch cdl_12 = new CountDownLatch(1); CountDownLatch cdl_22 = new CountDownLatch(2); //B类管理线程 executor.execute(new MonitorB(cdl_12, cdl_22)); //B类线程 executor.execute(new SelectTask("南京大学", list, queue, 10, 320, cdl_12, cdl_22)); //B类线程 executor.execute(new SelectTask("复旦大学", list, queue, 10, 320, cdl_12, cdl_22)); CountDownLatch cdl_13 = new CountDownLatch(1); CountDownLatch cdl_23 = new CountDownLatch(1); //C类管理线程 executor.execute(new MonitorC(cdl_13, cdl_23)); //C类线程 executor.execute(new SelectTask("南京职业技术学院", list, queue, Integer.MAX_VALUE, 250, cdl_13, cdl_23)); //处理未被录取考生线程 executor.execute(new NotSelectTask(list, queue, cdl_23)); } //从txt文档解析考生信息,并按总成绩进行排序 public List<SimpleStudent> parseTextFile(String filename) throws Exception { BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(filename), "UTF-8")); String line = null; List<SimpleStudent> students = new ArrayList<SimpleStudent>(); SimpleStudent stu; while (null != (line = reader.readLine())) { int index = line.indexOf("总分"); if (index == -1) continue; String score_str = line.substring(index + 3, line.indexOf(",", index)); stu = new SimpleStudent(Integer.parseInt(score_str), line); students.add(stu); } Collections.sort(students); return students; } }
-------------------执行结果 result_2.txt-------------------------
北京大学: 林衡 st018[总分:375, 英语: 93, 化学: 95, 代数: 96, 计算机: 91] 北京大学: 胡量 st019[总分:374, 英语: 98, 化学: 94, 代数: 93, 计算机: 89] 清华大学: 郑来 st017[总分:363, 英语: 89, 化学: 88, 代数: 90, 计算机: 96] 北京大学: 李方 st010[总分:344, 英语: 77, 化学: 86, 代数: 99, 计算机: 82] 北京大学:[达标] 当前录取3/总名额3 清华大学: 邹代 st020[总分:344, 英语: 87, 化学: 96, 代数: 79, 计算机: 82] 清华大学: 杨四 st004[总分:342, 英语: 78, 化学: 85, 代数: 83, 计算机: 96] 清华大学:[达标] 当前录取3/总名额3 复旦大学: 赵五 st005[总分:342, 英语: 79, 化学: 87, 代数: 91, 计算机: 85] 复旦大学: 赵度 st016[总分:342, 英语: 67, 化学: 98, 代数: 78, 计算机: 99] 复旦大学: 张一 st001[总分:340, 英语: 80, 化学: 90, 代数: 70, 计算机:100] 复旦大学: 李码 st021[总分:339, 英语: 77, 化学: 87, 代数: 89, 计算机: 86] 南京大学: 李二 st002[总分:320, 英语: 77, 化学: 88, 代数: 99, 计算机: 56] 复旦大学: 郑陆 st006[总分:320, 英语: 79, 化学: 87, 代数: 68, 计算机: 86] 南京大学:[未达标] 当前录取1/总名额10 复旦大学:[未达标] 当前录取5/总名额10 南京职业技术学院: 宁的 st022[总分:318, 英语: 94, 化学: 76, 代数: 69, 计算机: 79] 南京职业技术学院: 李度 st013[总分:310, 英语: 67, 化学: 87, 代数: 78, 计算机: 78] 南京职业技术学院: 王三 st003[总分:309, 英语: 96, 化学: 56, 代数: 88, 计算机: 69] 南京职业技术学院: 胡长 st008[总分:299, 英语: 69, 化学: 86, 代数: 75, 计算机: 69] 南京职业技术学院: 张杂 st012[总分:298, 英语: 44, 化学: 66, 代数: 99, 计算机: 89] 南京职业技术学院: 邹家 st009[总分:292, 英语: 84, 化学: 69, 代数: 90, 计算机: 49] 南京职业技术学院: 林世 st007[总分:291, 英语: 55, 化学: 78, 代数: 90, 计算机: 68] 南京职业技术学院: 宁可 st011[总分:279, 英语: 67, 化学: 87, 代数: 69, 计算机: 56] 南京职业技术学院:[达标] 当前录取8/总名额(无限制) 未被录取:张质 st023[总分:240, 英语: 87, 化学: 57, 代数: 48, 计算机: 48] 未被录取:王等 st014[总分:233, 英语: 56, 化学: 78, 代数: 88, 计算机: 11] 未被录取:杨角 st015[总分:209, 英语: 0, 化学: 44, 代数: 66, 计算机: 99]
发表评论
-
redis安装(windows.exe)
2014-05-21 22:54 740https://github.com/rgl/redis ... -
rabbitMQ安装(windows下)
2014-05-21 22:41 655进入项目下载主页面http://www.rabbitmq.co ... -
实现单线程的断点下载
2014-04-16 09:43 843/** * 实现单线程的断点下载 */ publ ... -
实现一个简易的http模拟器
2014-04-15 15:20 1799/** * http模拟器 * 模拟发送http请求和 ... -
xml学习
2014-04-08 22:47 1474XML:Extensible Markup Langu ... -
HTTP断点续传
2014-03-31 22:13 793http://fenglingcorp.iteye.com/b ... -
java多线程-线程状态转换
2014-03-01 09:20 7971. 新建(new):新创建了一个线程对象。 2. 可 ... -
apt处理自定义annotation
2014-02-19 23:20 1024package annotations; import ... -
跳过UTF-8的BOM
2014-02-14 12:19 1503/** version: 1.1 / 2007-01-25 ... -
java reference
2014-02-09 00:36 677import java.lang.ref.PhantomR ... -
不带头结点的单链表面试汇总
2014-01-24 13:47 1497import java.io.ByteArrayInputSt ... -
带头节点的单链表面试题汇总
2014-01-23 15:12 1031import java.io.ByteArrayInput ... -
单链表面试题之-链表反转
2014-01-15 22:43 1101单链表反转 -------------------- ... -
java单链表-带头结点和不带头结点单链表的简单实现
2014-01-14 23:41 4931带头结点的单链表实现 public class LinkedL ... -
ClassLoader
2013-11-08 15:57 908public class ClassLoaderTest { ... -
URL和URI
2013-11-08 13:48 513private static void getData ... -
i++和++i
2013-11-06 15:26 524// i = i++ 计算过程 // temp = i; ... -
java 继承 多态
2013-11-06 15:19 802/** 运行结果: A's constructor co ... -
sealing violation
2013-11-03 16:10 3140一般以下两种情况会触发sealing安全异常 1)当被密封(s ... -
hashmap分析
2013-10-30 15:20 693/** hashmap底层维护着一个entry数组,每 ...
相关推荐
【标题】华为2009年软件公司技能...通过学习这些文档和代码,Java开发者可以系统地复习和提升编程技能,尤其是针对华为的技能鉴定标准。同时,这些资料也可以作为日常学习和项目开发的参考资料,加深对Java编程的理解。
通过学习RSS,实习生可以了解到XML应用的基本原理和技术。 知识点五:XSLT和XPath的应用 XSLT(eXtensible Stylesheet Language Transformation)是一种用于转换XML文档结构的语言,而XPath是一种用于在XML文档中...
通过"JAVA技能鉴定试题_第二套"和"JAVA技能鉴定试题_第二套答案"这两个文档,你可以对上述知识点进行深入学习和练习,以提高你的Java技能水平。这份鉴定不仅测试了理论知识,还评估了实际编程和问题解决能力,是成为...
实习鉴定表和实习报告是衡量实习生在实习期间学习、工作情况的重要文档,通常由实习单位和学校共同评估。福建农林大学计算机与信息学院的实习报告要求详细且规范,旨在提升学生的实践技能和专业知识。 一、实习报告...
### 计算机专业大学生实习鉴定相关知识点 #### 一、计算机软件技能 - **办公软件**:Office XP,包括Word、Excel、PowerPoint等,是办公自动化的重要工具,掌握这些软件可以有效提升工作效率和质量。 - **图形设计...
"labels"文件夹包含每个图像对应的标注信息,这些信息通常以XML或CSV格式存储,列明了每个目标物体的边界框坐标以及对应的类别标签。"images"文件夹则包含实际的图像文件,这些图片可用于训练和验证深度学习模型。 ...
+ 进阶学习目标 4. 技能要求 * 专业知识要求: + Microsoft .NET 框架和 Microsoft Visual Studio .NET 集成开发环境的主要概念 + C# 语言的基本原理 + 对象的创建 + 面向对象的编程技术 + 使用 ADO...
- **ASP.NET应用程序开发**:涉及.NET Framework概述、Web窗体创建、代码添加、用户验证、数据访问、XML Web Service等。 - **SQL Server 2000数据库应用和管理**:包括数据库管理系统基础、数据模型、Transact-...
【描述】提到的"从别处找的重庆大学的课件,大家给鉴定一下!"表明这是一个共享资源,可能来自互联网上的学习社区或个人分享。用户希望其他人能够验证这些课件的质量和准确性,以确保它们可以作为学习J2EE的有效资料...
下面我们来学习学习这个咚咚,希望能给更多的人带来帮助。 首先当然是要了解一下浏览器中的XMLHttp对象了: XMLHTTP方法: 备注:客户机可以使用XMLHTTP对象发送任意的HTTP请求,接受HTTP应答,还可以对应答的XML文档...
国内自主研发的监测设备由于缺乏标准化鉴定,难以进入市场,导致高端海洋仪器市场被国外产品主导。 海洋监测系统的主要功能包括实时采集海洋基本监测要素,如水温、盐度、pH值和硅酸盐等,通过无线GPRS网络实现实时...
邮票鉴赏系统是一种在线平台,它允许用户浏览、学习和分享关于邮票的知识,同时提供鉴定服务。这个系统是基于SSM(Spring、SpringMVC、MyBatis)框架和Web技术构建的,旨在为集邮爱好者提供一个便捷、互动的交流环境...
自演化智能软件系统平台是一种革命性的软件开发平台,它与传统静态软件平台不同,能够根据不同的使用案例和场景,通过经验学习和演进来改变自身的架构。这种平台的设计理念和技术研究涉及以下几个关键知识点: 1. ...
1. 构建"互联网+"档案管理新模式:档案管理应当超越传统的收集、保管和使用,通过XML、Web Services等技术实现不同系统间的集成,打破信息孤岛,增强档案信息的完整性,为决策提供数据支持。 2. 加强档案资源体系...
- **了解前置知识**:为了更好地学习Spring Security,读者需要具备一定的基础知识,包括但不限于AOP(面向切面编程)、Servlet等相关概念;如果熟悉Java语言则更易于理解Spring Security的相关概念和操作。 #### ...
- **知识点解析**:根据《档案管理软件功能要求暂行规定》,档案管理软件的数据交换格式应支持 DBF 格式和 XML 文档。这两种格式都广泛应用于数据交换领域,便于不同系统之间的数据共享和交互。 **16. 日志文件保存...
ProteomicsDB是一个全球性的蛋白质组学数据库,存储了大量的实验数据,包括蛋白质鉴定、定量、相互作用以及功能注释等。它提供OData服务,使得科研人员可以通过API直接访问这些数据,进行数据分析和研究。 ...
【批发鸡蛋的软件】是一款基于Visual Basic...通过学习和理解源代码,用户不仅可以自定义软件功能,还能增进对VB编程的理解,为未来的技术扩展打下基础。在使用过程中,商家应注意数据安全和备份,确保业务的稳定运行。