标签:自己 syn ret array 就是 同步 资源竞争 rod 想法
有关创建线程的知识就不过多的叙述了。就从主要的开始讲吧,讲一下线程的同步。与操作系统中的进程同步一样,线程同样面临着资源共享的问题,怎样处理线程的资源共享是运用多线程最重要的地方。在Java中是引入锁这一概念来处理多线程之间的资源竞争的关系的。“锁”的对象可以是代码块,方法,还可以是对象。一旦某一部分被锁住,我们称该部分获取了锁。那么在java多个线程中,只有拥有锁的线程才可以运行,其他线程不能运行。如果我们将竞争资源的代码块锁起来,就可以避免发生冲突。在运用锁的过程中,通常使用的是synchronized();表示锁住某一部分代码块。那么我们还介绍以下,wait(),和notifyAll(), notify的用法。举个例子,以多线程电梯为例子吧,在多线程电梯中的输入与1调度器之间的关系。我们一次输入同一时刻的多条指令,我们将这多条指令称为临时队列。每次调度每一次输入的指令,将每一次输入的指令加入到总的队列中去。那么就要求输入的时候,不可以运行调度器访问输入的临时队列,因为如果多次访问将造成一次输入被调度多次,而调度的时候也不能写入指令,因为多次写入会导致重写前一次的输入,也就忽略了前一次的输入。看一下代码:
while(true) { while(this.sign!=0) { //表示队列不为空 try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } /** 表示中间处理过程 */ sign=1; //用于标记 notifyAll(); }
二.三次作业分析
刚刚接触多线程确实是十分的艰难,刚拿到的时候毫无头绪。最后的成绩也不是很好,不过之后debug之后感觉就好多了。首先看一下JProfiler性能分析的结果。
用wait()方法锁住的线程表示为红色,在输入阶段CPU的使用也是最多的,然后是三个电梯都接收指令后开始调度。最后输入END后输入线程结束,还有电梯没有执行完。直到执行完后结束。分为三个阶段的化输入的时候也会有调度,所以处理器的使用率最高,然后是三部电梯同时调度,最后是一部电梯调度,可以看出三部电梯同时调度的时候CPU的使用要比单个电梯调度的时候高很多。说明除了运行线程,CPU处理线程之间的调度也占用CPU。
https://en.wikipedia.org/wiki/IFTTT,或者,https://baike.baidu.com/item/ifttt/8378533?fr=aladdin,而IFTTT本事也是一款十分强大的app,大家可以去试试,https://ifttt.com/products。
由于对于这次的测试,测试文件不是很多,所以CPU的使用比较低。从图中可以明显的看出我存在的一个问题,那就是没有一直监控文件。再之后我会说明。一个输入会增加一个线程,也就是说,每一个文件对应一个监控线程,用来实时监控改文件。对于为什么会有线程结束,是因为,再我的程序中,监控文件只会监控一次变化,但是监控目录会监控多次变化。在类图部分会说明原因。开始阶段CPU的使用增长主要时输入的时候需要创建线程的原因。
这次的类图明显比较乱
class File_all {protected String name=null; protected long f_l=0; protected long l_t=0; protected String path=null; }
由于File方法返回的是指向文件的指针,那么当路径改变的时候,返回值就会改变,所以,File_all的作用是存入路径改变之前的文件的属性,用于之后的文件改变后用于比较。那么是如何获取整个目录下所有的文件的呢?当然是使用递归搜索的方法。
class Test { protected void test(String fileDir, ArrayList<File_all> fileList) { // = new ArrayList<File_all>(); File file = new File(fileDir); File[] files = file.listFiles();// 获取目录下的所有文件或文件夹 if (files == null) {// 如果目录为空,直接退出 return ; } // 遍历,目录下的所有文件,将文件属性存起来 for (File f : files) { File_all tem_file = new File_all(); if (f.isFile()) { tem_file.file = f; tem_file.name = f.getName(); tem_file.f_l = f.length(); tem_file.l_t = f.lastModified(); fileList.add(tem_file); } else if (f.isDirectory()) { test(f.getAbsolutePath(),fileList); } } return ; } }
if(file_2.isDirectory()) { chose = 0; ArrayList<File_all> FileList = new ArrayList<File_all>(); //新建FileList存储旧的文件 test_sc.test(obj_path,FileList); //递归获取旧的文件属性,并存储 while(true) { ArrayList<File_all> FileList2 = new ArrayList<File_all>(); //新建新文件 test_sc.test(obj_path,FileList2); //递归获取新的文件属性,并存储 /** 各种操作 */ FileList.clear(); //各种比较操作结束后,也就是将新旧文件比较后,清空新旧文件 FileList2.clear(); test_sc.test(obj_path,FileList); //再一次获得旧文件,存储旧文件,用于之后比较 try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } }
度量分析的结果显示,代码还是有漏洞。
出租车的测试,我采用了一次性输入了大量的请求。从CPU运行的几个峰值来看,第一个是程序开始,创建100个出租车线程,可以看出创建线程是比较占用CPU的,然后是每一次输入,每一次输入是比较占用CPU的,原因是,每一个输入或构建一个调度线程,同样需要创建多个线程,就导致CPU的运行大大增加。中间会有一些较小的峰值,是出租车的运行。
while(true) { direction = (int)(1+Math.random()*5); //随机选一个位置 if(direction==1 && this.location_x<79 && map_mess.graph[location][location_1]==1) { this.location_x = this.location_x+1; break; } else if(direction==2 && this.location_x>0 && map_mess.graph[location][location_2]==1) { this.location_x = this.location_x-1; break; } else if(direction==3 && this.location_y>0 && map_mess.graph[location][location_3]==1) { this.location_y = this.location_y-1; break; } else if(direction==4 && this.location_y<79 && map_mess.graph[location][location_4]==1) { this.location_y = this.location_y+1; break; } }
由于是连通图,所以总会有路走的。
可以看出各个类之间的关系
第一次圈复杂度过关了,是不是很高兴,但是这其实是假的。经过多次测试,我发现问题,真实情况是这样的:
然而原因是,我太着急了,第一张图是还没有完全测试完的情况还没有完全显示出圈复杂度。
老实说,我其实每次作业都是抱着,只要有效就行的想法写的,所以最后写的也不是特别好,这三周真的是十分的艰难啊。第一周的时候想到一句话:“No Pains ,No Gains” 。再咬咬牙吧,第二周的时候又想到一句话“如果有一天,你觉得生活如此的艰难,那也许是这次的收获将十分的巨大”。第二周的时候,第三次作业都快想放弃了,生命要紧啊,后来还是咬咬牙坚持了下来,因为又想到一句话”将来的你,一定会感谢现在如此努力的自己“。在这十分艰难的日子里,我也只能靠这些鸡汤度日了。所以想和大家共勉吧,来 ”干了这碗鸡汤“。
标签:自己 syn ret array 就是 同步 资源竞争 rod 想法
原文地址:https://www.cnblogs.com/wevolf/p/8968897.html