图书馆仿真
这是我一次仿真的尝试,但是老实说,自我感觉并不是很好,因为有关于线程的问题并没有想清楚,而且,真的,线程这种东西真的是很让人头晕啊,虽然我看书的时候,对于那些基础的知识点是能够理解,但是自己写代码的时候,就发现一个问题,就是现实生活中的实际模型复杂得很,不是书上几个例子就能涵盖的,看来我还是得慢慢捉摸这块,毕竟并发这块在现代越来越重要,尤其是现在交互式已经烂大街了。好吧,我先说明一下,这次我的仿真对象是什么,只是一个模拟中间有一个中转台的图书馆查询系统,就像是前台你跟服务员说一下你想要找的书,然后,然后服务员传达给中转台,中转台在它的库里寻找相关的内容,然后生成一份名单,名单上有这些书的评分,接着再到图书馆里寻找,毕竟图书馆里面的书的信息已经更换过了或者被别人借走了,假设中转台的信息是比较落后的。 首先,说一下我的代码的执行流程,首先,我一个方法是用来让用户输入关键字的,然后将这个关键字传给中转台,使它能够根据这个关键字在它的信息库里找出相应的图书,接着就是将这份名单传给图书馆,图书馆再进一步看看它的信息库里有没有包含该书,然后就是显示出来。这个过程,我们可以看到一点,就是如果用户没有输入关键字,那个整个流程根本就不会开始,接着就是中转台如果没有生成名单,那么,图书馆也就不会运行,也就不会有任何东西显示出来。那么,这个过程可以向下面那样进行:
用户输入关键字--->中转台开始搜索图书信息,这时,如果没有名单交给图书馆,那么,图书馆这边应该告诉用户,现在正在检索中,等到图书馆开始工作时,如果没有生成名单,那么,正在检索的信息依然还在控制台上显示,知道图书馆这边生成名单,就会告诉用户,检索完毕,然后将名单显示出来,中间的确没有什么共享的资源,因为它们之间的关系并不是竞争,更像是一种传递,只有前面一个流程结束,后面才能开始,那么,线程要如何体现呢?我觉得,所谓的线程,也就是一直在运转的线程就是那个所谓的正在检索中吧,因为它所贯穿的是两个过程,也就是说,这个线程的开始是在输入关键字开始,图书馆开始生成名单后结束,那么,我就能这么写,当关键字输入完后,这个线程就被唤醒,然后这个线程直到图书馆生成名单后挂起。那,我不应该将之前三个过程分开,因为它们其实是在一块的逻辑,在这块的逻辑中,决定什么时候将检索这个线程唤醒和挂起而已。,好吧,试试看,然后,再得到这个运行的时间,来看看检索的时间到底有多长。
然后上代码:
public class Library { private static long startTime = 0; private static long endTime = 0; @SuppressWarnings("deprecation") public static void main(String[] args) throws InterruptedException { Thread t = new Thread(new Call()); String name = enterName(); List<RatingBook> ratingList = checkName(name, t); List<RatingBook> bookList = getBook(ratingList); int flag = 0; for (int i = 0; i < bookList.size(); i++) { if ((bookList.get(i).getBook()).equals("")) { flag++; } } if (flag == bookList.size()) { t.stop(); endTime = System.currentTimeMillis(); System.out.println("图书馆没有书!" + "检索所需时间为:" + "\n" + (endTime - startTime)); } else { sortBook(bookList); t.stop(); endTime = System.currentTimeMillis(); for (int i = 1; i < bookList.size(); i++) { if (!(bookList.get(i).getBook().equals(""))) { RatingBook book = bookList.get(i); showInfor("图书馆里的图书列表:", book); } } System.out.println("检索所需时间为:" + "\n" + (endTime - startTime)); } } //显示书本的内容 private static void showInfor(String string, RatingBook book) { System.out.println(string + book.getBook() + " 评分:" + book.getRating()); } //按照评分的高低来将名单进行排列 private static void sortBook(List<RatingBook> list) { for (int i = 0; i < list.size() - 1; i++) { for (int j = i + 1; j < list.size(); j++) { if ((list.get(i).getRating()) < (list.get(j).getRating())) { String temp = list.get(i).getBook(); int rating = list.get(i).getRating(); list.get(i).setBook(list.get(j).getBook()); list.get(i).setRating(list.get(j).getRating()); list.get(j).setBook(temp); list.get(j).setRating(rating); } } } } private static List<RatingBook> checkName(String name, Thread t) { t.start(); startTime = System.currentTimeMillis(); List<RatingBook> list = new ArrayList<RatingBook>(); List<RatingBook> nlist = new ArrayList<RatingBook>(); for (int i = 0; i < new Random().nextInt(10); i++) { RatingBook book = new RatingBook(); bookLibrary bookArray = new bookLibrary(); book.setBook(bookArray.bookArr1[new Random().nextInt(11)]); book.setRating(new Random().nextInt(6)); list.add(book); } for (int i = 0; i < list.size(); i++) { String book = list.get(i).getBook().toLowerCase(); showInfor("中转台图书列表:", list.get(i)); if (book.contains(name)) { showInfor("有该书:", list.get(i)); nlist.add(list.get(i)); } else { showInfor("要删除的图书:", list.get(i)); } } showList("现在的图书列表:", nlist); sortBook(nlist); showList("符合条件的图书列表:", nlist); return nlist; } //显示名单的内容 private static void showList(String string, List<RatingBook> list) { for (int i = 0; i < list.size(); i++) { if (!(list.get(i).getBook().equals(""))) { System.out.println(string + list.get(i).getBook() + " 评分:" + list.get(i).getRating()); } } } //让用户输入关键字进行查找 private static String enterName() { BufferedReader name = new BufferedReader(new InputStreamReader( System.in)); String entername = null; try { entername = name.readLine().toLowerCase(); } catch (IOException e) { e.printStackTrace(); } return entername; } //模拟图书馆的生成名单,就是图书馆会根据里面有没有来将中转台传过来的名单进行修改,如果有,就加上中转台里面的评分信息
private static List<RatingBook> getBook(List<RatingBook> ratingList) { List<RatingBook> bookList = new ArrayList<RatingBook>(); List<RatingBook> nbookList = new ArrayList<RatingBook>(); RatingBook FlagBook = new RatingBook(); FlagBook.setBook(""); nbookList.add(FlagBook); for (int i = 0; i < new Random().nextInt(20); i++) { RatingBook book = new RatingBook(); bookLibrary bookArray = new bookLibrary(); book.setBook(bookArray.bookArr2[new Random().nextInt(13)]); book.setRating(0); bookList.add(book); } for (int i = 0; i < bookList.size(); i++) { for (int j = 0; j < ratingList.size(); j++) { if ((bookList.get(i).getBook().toLowerCase()) .contains((ratingList.get(j).getBook().toLowerCase()))) { bookList.get(i).setRating(ratingList.get(j).getRating()); nbookList.add(bookList.get(i)); } else { nbookList.add(FlagBook); } } } return nbookList; } } //模拟前台服务员小姐常常说的:“现在正在等待中。。”这也是我这里面唯一一个附加的线程! class Call implements Runnable { @Override public void run() { System.out.println("正在检索中"); } }
运行的结果如:
java
正在检索中
中转台图书列表:javascript 评分:5
有该书:javascript 评分:5
中转台图书列表:java 评分:1
有该书:java 评分:1
现在的图书列表:javascript 评分:5
现在的图书列表:java 评分:1
符合条件的图书列表:javascript 评分:5
符合条件的图书列表:java 评分:1
图书馆里的图书列表:java and SQL 评分:1
图书馆里的图书列表:java and SQL 评分:1
图书馆里的图书列表:java and SQL 评分:1
检索所需时间为:
4
唉,说是仿真,但是我觉得这里面跟并发一点关系都没有,只是我自己强加上一个线程而已,但是我现在的水平又想不出什么好的主意来,只能先放在博客上,希望哪个大神看到能提个醒,毕竟小弟现在还是新手,很多问题根本就无从下手啊!!!
经过我的第一次重构后,这次,先就代码的可读性下手,并没有考虑到性能,所以,有关于线程,排序等等,这些东西,先放一边,我就直接上代码:
public class Library { @SuppressWarnings("deprecation") public static void main(String[] args) throws InterruptedException, IOException { long endTime = 0; String name = enterName(); Thread t = new Thread(new Call()); t.start(); long startTime = System.currentTimeMillis(); List<RatingBook> doubanList = checkNameAndShowBookInDouban(name); List<RatingBook> libraryList = getBookFromLibrary(doubanList, name); sortBook(libraryList); t.stop(); endTime = System.currentTimeMillis(); System.out.println("图书馆里的图书列表:"); for (int i = 0; i < libraryList.size(); i++) { if (!(libraryList.get(i).getBook().equals(""))) { RatingBook book = libraryList.get(i); showInfor(book); } } System.out.println("检索所需时间为:" + "\n" + (endTime - startTime)); } private static String enterName() throws IOException { BufferedReader name = new BufferedReader(new InputStreamReader( System.in)); String entername = name.readLine().toLowerCase(); return entername; } private static List<RatingBook> checkNameAndShowBookInDouban(String name) { List<RatingBook> mlist = new ArrayList<RatingBook>(); List<RatingBook> list = createAndReturnBookInZhongZhuanTai(); RatingBook[] containsBook = new RatingBook[list.size()]; RatingBook[] deleteBook = new RatingBook[list.size()]; System.out.println("中转台图书列表:"); for (int i = 0; i < list.size(); i++) { String book = list.get(i).getBook().toLowerCase(); showInfor(list.get(i)); if (book.contains(name)) { containsBook[i] = list.get(i); mlist.add(list.get(i)); } else { deleteBook[i] = list.get(i); } } System.out.println("中转台符合条件的图书:"); showInfoOfCheck(containsBook); System.out.println("要删除的图书:"); showInfoOfCheck(deleteBook); System.out.println("符合条件的图书列表:"); showList(mlist); return mlist; } private static List<RatingBook> createAndReturnBookInZhongZhuanTai() { List<RatingBook> list = new ArrayList<RatingBook>(); for (int i = 0; i < returnIndex(10); i++) { RatingBook book = new RatingBook(); bookLibrary bookArray = new bookLibrary(); book.setBook(bookArray.doubanBookList[returnIndex(11)]); book.setRating(returnIndex(6)); list.add(book); } return list; } private static int returnIndex(int i) { return new Random().nextInt(i); } private static void showInfor(RatingBook book) { if (book == null) { } else { System.out.println(book.getBook() + " 评分:" + book.getRating()); } } private static void showInfoOfCheck(RatingBook[] BookArr) { for (int i = 0; i < BookArr.length; i++) { showInfor(BookArr[i]); } } private static void showList(List<RatingBook> list) { sortBook(list); for (int i = 0; i < list.size(); i++) { if (!(list.get(i).getBook().equals(""))) { System.out.println(list.get(i).getBook() + " 评分:" + list.get(i).getRating()); } } } private static void sortBook(List<RatingBook> list) { List<RatingBook> mlist = removeSameBook(list); sortBookByRating(mlist); } private static List<RatingBook> removeSameBook(List<RatingBook> list) { for (int i = 0; i < list.size() - 1; i++) { for (int j = i + 1; j < list.size(); j++) { if ((list.get(i).getBook()).equals(list.get(j).getBook())) { list.remove(j); } } } return list; } private static void sortBookByRating(List<RatingBook> list) { for (int i = 0; i < list.size() - 1; i++) { for (int j = i + 1; j < list.size(); j++) { if ((list.get(i).getRating()) <= (list.get(j).getRating())) { String temp = list.get(i).getBook(); int rating = list.get(i).getRating(); list.get(i).setBook(list.get(j).getBook()); list.get(i).setRating(list.get(j).getRating()); list.get(j).setBook(temp); list.get(j).setRating(rating); } } } } private static List<RatingBook> getBookFromLibrary(List<RatingBook> list, String name) { List<RatingBook> bookList = new ArrayList<RatingBook>(); List<RatingBook> mBookList = new ArrayList<RatingBook>(); for (int i = 0; i < returnIndex(12); i++) { RatingBook book = new RatingBook(); bookLibrary bookArray = new bookLibrary(); book.setBook(bookArray.libraryBookList[returnIndex(13)]); book.setRating(0); bookList.add(book); } for (int i = 0; i < bookList.size(); i++) { if ((bookList.get(i).getBook()).contains(name)) { mBookList.add(bookList.get(i)); } } for (int i = 0; i < mBookList.size(); i++) { for (int j = 0; j < list.size(); j++) { if ((mBookList.get(i).getBook()) .equals((list.get(j).getBook()))) { mBookList.get(i).setRating(list.get(j).getRating()); } } } return mBookList; } }
然后我就是将那个Runnable类移到其他文件里,就是这样,不知道大家认为可读性是不是比以前提高了,代码运行效果如下:
java
正在检索中
中转台图书列表:
java and c 评分:1
sql 评分:5
INT 评分:1
INT 评分:5
ZHENGWENBIAO 评分:3
javascript 1 评分:3
中转台符合条件的图书:
java and c 评分:1
javascript 1 评分:3
要删除的图书:
sql 评分:5
INT 评分:1
INT 评分:5
ZHENGWENBIAO 评分:3
符合条件的图书列表:
javascript 1 评分:3
java and c 评分:1
图书馆里的图书列表:
javascript 评分:0
检索所需时间为:
4