1. 本周学习总结
1.1 以你喜欢的方式(思维导图或其他)归纳总结异常与多线程相关内容。
2. 书面作业
本次PTA作业题集异常、多线程
finally
题目4-2
1.1 截图你的提交结果(出现学号)
1.2 4-2中finally中捕获异常需要注意什么?
需要注意的是open抛出的异常是Exception
而close抛出的异常是RuntimeException
需要对不同的异常形式进行捕获
用异常改进ArrayIntegerStack
题目4-3
2.1 截图你的提交结果(出现学号)
2.2 实验总结
原本用try-catch的形式进行捕获,不需要对栈满栈空的情况进行判断
直接放入try中进行捕获,然后答案出错了- -
之后改用直接判断条件,然后抛出异常
一个小小的该注意的点是编写peek函数的时候不能和pop函数一样用arrStack[--top]
应该用arrStack[top-1],因为peek只是查看栈顶元素,不删除
读取文件并组装对象
实验任务书中中的题目3:读取文件并组装对象
给出关键代码(需出现你的学号)
public class Main201521123065{
public static void main(String[] args) throws FileNotFoundException {
Scanner in = new Scanner(new File("身份证号.txt"));// 为myfile.txt这个File创建一个扫描器in
ArrayList<User> list=new ArrayList<User>();
while (in.hasNextLine()) {
String line = in.nextLine();// 读出myfile.txt的下一行
Scanner lineScanner = new Scanner(line);// 为每一行建立一个扫描器
// System.out.println("lineScanner="+lineScanner);
lineScanner.useDelimiter(" ");// 使用空格作为分隔符
// System.out.println(line);
try{
String a1;
String a2;
String a3;
String a4;
String a5;
a1 = lineScanner.next();
a2 = lineScanner.next();
a3 = lineScanner.next();
a4 = lineScanner.next();
a5 = lineScanner.next();
while (lineScanner.hasNext()) {// 谨防地址只有一段
a5 += lineScanner.next();
}
int k=Integer.parseInt(a4);
User user=new User(a1,a2,a3,k,a5);
list.add(user);
System.out.println(a1 + a2 + a3 + a4 + a5);
}catch(Exception e){
}
}
Collections.sort(list,new AgeComparator());age排序后输出
System.out.println(list);
in.close();
}
}
class AgeComparator implements Comparator<User>{//年龄比较器,对User的Age进行排序
@Override
public int compare(User o1, User o2) {
// TODO Auto-generated method stub
return o1.getAge()-o2.getAge();
}
}
自定义异常
题目5-4
4.1 截图你的提交结果(出现学号)
4.2 自定义异常有哪几个关键点?
1、自定义的异常需要继承自Throwable或者Exception,后面捕获异常可以直接使用一句catch(Exception e)即可;
2、自定义异常里面的构造函数需要用super函数;
3、善于用java中自定义的类判断首字母是否为一个数字(import java.util.regex.Pattern;Character.isDigit);
4、将接受姓名的sc.nextLine置换为sc.next
5、当只有输入一个姓名的时候,或者说当姓名与成绩之间没有空格分隔开的时候,打印出java.util.NoSuchElementException的信息是建立在下一个输入为非Int型的前提之下;
6、最后输入other时会将Scanner关闭并打印。
学会使用Eclipse进行调试
观看相关调试视频
5.1 简述使用Eclipse进行调试需要几步?
1、根据错误信息判断出错的地方设置断点
2、启动Debug模式进入调试;
3、根据需要对设置断点的地方进入该函数(F5),跳过该行或函数(F6),跳出这个函数(F7)
4、鼠标移动到变量处右键点击watch可查看当前属性
5、清楚断点结束该程序。
5.2 调试时F5, F6, F7快键键各有什么不同?什么情况该使用哪个快捷键?
F5:(step into)进入函数进行调试;
F5:(step over)跳过这行或者跳过这个函数;
F7:(step return)当还未执行完函数但想停止时可以跳出这个函数。
5.3 除了Eclipse的调试器,你还使用什么方法调试程序?
还可以在出错的地方前后用system.out.println()进行打印
查看后续操作是否会执行
多数在当循环函数出现问题时使用system.out.println();
例如T5-4题目中,一开始运行时发现输入了一次就打印了sc.closed
于是在while循环的末尾处进行了system.out.println操作
找出了原因是因为使用了sc.nextLine()将换行符也接受,因此判断不是newz字符时就退出循环打印
题集多线程
6.1 程序填空3-1、3-2。(截图提交结果,出现你的学号)
3-1、3-2
6.2 函数4-1(Thread)、4-2(Runnable)(截图提交结果,出现你的学号)
4-1
4-2
6.3 函数4-3(Runnable与匿名内部类)(截图提交结果,出现你的学号),并使用Labmda表达式改写。
Labmda表达式
6.4 实验总结
1、填空题:要求主线程退出时main方法中的线程也同时结束可以用守护线程的方法
需要注意的是,无论是变为一般线程(即程序是在最后一个线程结束时才结束),或是同时结束时,都要在线程之前调用;
2、4-2:run方法中,需要在最后将word置为null,防止被重复接受,因此,在判断是否是外星人之前需要判断word是否不为null,否则不进入
同时,应该将this.word.equals("alien")按照题目的要求改为this.word.contains("alien"),否则会导致线程终止出错
3、4-3:获取主线程名时不需要将t1线程sleep,因为在启动线程之前有用String变量对当前线程名进行存储
源代码阅读:多线程程序BounceThread
7.1 哪个类是支持多线程的类,它实现了什么接口。这个类做了些什么?
class BallRunnable implements Runnable
{
/**
* Constructs the runnable.
* @aBall the ball to bounce
* @aPanel the component in which the ball bounces
*/
public BallRunnable(Ball aBall, Component aComponent)
{
ball = aBall;
component = aComponent;
}
public void run()
{
try
{
for (int i = 1; i <= STEPS; i++)
{
ball.move(component.getBounds());
component.repaint();
Thread.sleep(DELAY);
}
}
catch (InterruptedException e)
{
}
}
BallRunnable类是支持多线程的类,实现了Runnable接口,
这个类主要是定义了BallRunnable这个任务,并且对球的属性组成进行了定义
在定量小球个数循环内部,move函数用于让小球弹动,repaint函数将小球组件重置,并让当前线程暂停好让其他小球进行跳动
7.2 Ball.java这个程序只做了两件事,这两件事分别是什么?
/**
Moves the ball to the next position, reversing direction
if it hits one of the edges
*/
第一件事:是对move函数的声明
move的功能在于将小球移动到下一个位置,如果碰到边缘的话就转换方向直到结束
/**
Gets the shape of the ball at its current position.
*/
public Ellipse2D getShape()
{
return new Ellipse2D.Double(x, y, XSIZE, YSIZE);
}
private static final int XSIZE = 15;
private static final int YSIZE = 15;
private double x = 0;
private double y = 0;
private double dx = 1;
private double dy = 1;
}
第二件事:获取小球当前形状,并对小球的形状属性进行定义声明
7.3 BallComponent也只做了两件事,这两件事分别是什么?
public void add(Ball b)
{
balls.add(b);
}
public void paintComponent(Graphics g)
{
Graphics2D g2 = (Graphics2D) g;
for (Ball b : balls)
{
g2.fill(b.getShape());
}
}
1、add()添加小球
2、绘制小球组件,对小球进行填充
7.4 BounceThread中,什么时候启动了新线程?
public class BounceThread
{
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
JFrame frame = new BounceFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
});
}
}
EventQueue.invokeLater()用匿名内部类对run进行了定义,从而启动线程
7.5 这个程序是如何实现?一个大致的执行流程是什么?
1、匿名内部类声明任务,启动BallRunnable(implememts Runnable)
2、构建完小球运动边缘框架,对小球运动和属性进行声明
3、声明方法的同时对小球的运动轨迹进行设定,当碰到边缘则重置方向
4、对有上限个小球进行多线程的运行,直到结束
购物车系统中的多线程
8.1 购物车系统中可能存在哪些多线程问题?
比如当这个系统功能增大到可以多个用户同时购物进行操作时需要多线程操控
并且当单个用户进行商品的挑选时,商品的数量此时正减少或者退货的增加
或者购物系统中同时有购买东西和订外卖的功能,当你逛东西逛到饭点时想订外卖,而此时点开外卖界面又同时购物界面也一样存在着,这也用到了多线程问题
3. 码云上代码提交记录
题目集:异常、多线程(3-1, 3-2, 4-1, 4-2, 4-3)
3.1. 码云代码提交记录
在码云的项目中,依次选择“统计-Commits历史-设置时间段”, 然后搜索并截图