zoukankan      html  css  js  c++  java
  • 201621123037 《Java程序设计》第11周学习总结

    作业11-多线程

    标签(空格分隔): Java


    1. 本周学习总结

    1.1 以你喜欢的方式(思维导图或其他)归纳总结异常相关内容。


    2. 书面作业

    本次PTA作业题集多线程

    1. 源代码阅读:多线程程序BounceThread

    1.1 BallRunnable类有什么用?为什么代码中需要调用Thread.sleep进行休眠?

    答:

    作用:
    BallRunnable类实现了Runnable接口之后,可以多个程序的线程处理同一资源,其中运用run()方法给线程分配任务。run()方法中通过循环用move()方法来控制小球的移动,用reprint()方法来重画轨迹,Treep.sleep()方法实现休眠。

    原因:
    Treep.sleep()方法是让线程进行休眠一段时间,因为系统执行这个移动小球和重画的过程非常的快,如果不休眠一段时间,我们运行起来是看不到小球的运动轨迹的。

    1.2 Ball.java只做了两件事,这两件事分别是什么?BallComponent对象是干什么的?其内部的ArrayList有什么用?程序运行过程中,生成了几个BallComponent对象?该程序使用了多线程技术,每个小球是分别在不同的线程中进行绘制吗?

    答:

    两件事:

    • 定义move()方法来控制小球的移动
    • 定义getShape()方法来获取此小球的位置的形状

    BallComponent对象:

    • public void add(Ball b)添加一个小球
    • public void paintComponent(Graphics g)绘制小球的轨迹

    内部的ArrayList:
    用来动态存储多个小球的对象

    运行过程:
    生成了1个BallComponent对象

    多线程技术:
    是在不同的线程中绘制的。代码运行起来后,点击Start按钮,每点击一次生成一个小球,然后小球按照规定轨迹运行。生成的小球即一个线程,故每个小球都是在自己的线程中进行的绘制。

    1.3 选做:程序改写:程序运行时,每个小球都是从固定位置出发。如何改写该程序,使得当点击start时,每个小球可以从不同位置出发、以不同的步进移动?

    答:

    因为在move()方法中控制小球的移动,其中控制的方法都牵扯到了变量x,y,dx,dy。所以,如果在最开始生成x,y,dx,dy变量时就都随机的话,那么小球的运动轨迹和运动时间都对完全不同,即更改如下图:

    运行结果:

    2. 实验总结:题集(多线程)

    2.1 题目:Thread、PrintTask、Runnable与匿名内部类。

    并回答:a)通过定义Runnable接口的实现类来实现多线程程序比通过继承自Thread类实现多线程程序有何好处?b) 6-1,6-3,6-11实验总结。

    Runnable接口好处:

    • java不允许多继承,因此实现了Runnable接口的类可以再继承其他类。
    • 方便资源共享,如果extends Thread的话,开启多个线程数据不是共享的,例如:
    public class xx extends Thread{
        int num = 0;
        public void run(){
            for(int i = 0; i < 10; i++){
                System.out.println(++num);
            }
        }
        //运行主函数
        public static void main(String[] args){
            new xx().start(); //没new一次,就会产生一次num
            new xx().start(); //这个new,那么num属于这个的。
        }
    }
    //下面是implementes Runnable接口
    public class xx implementes Runnable{
        xxxx//这里代码如上
         public static void main(String[] args){
             xx x1 = new xx();
             Thread t1 = new Thread(x1);
             t1.start();
             Thread t2 = new Thread(x1);
             t2.start();
             //这里我们可以看到,无论创建几个线程,都是传入的x1
         }
    }
    

    6-1,6-3,6-11实验总结:

    jmu-Java-07多线程-Thread:
    这道题重点在于题目中n值的传入,所以要在类中定义一个有参构造函数,将传入的n值保存下来,其他的按照要求即可

    jmu-Java-07多线程-Runnable与匿名类:
    这道题重点在于主线程和t1线程的名称:
    System.out.println(mainThreadName);
    System.out.println(Thread.currentThread().getName());
    其他就补全run()方法就好了

    jmu-Java-07多线程-PrintTask:
    这道题和6-1没有什么不同啊= =。 可能只有标示信息不一样吧

    2.2 使用Lambda表达式改写6-3

    答:

    Thread t1 = new Thread(() -> {
    			System.out.println(mainThreadName);
    			System.out.println(Thread.currentThread().getName());
    			System.out.println(Arrays.toString(Thread.class.getInterfaces()));
    		});
    

    2.3 题目:6-2(Runnable与停止线程)。回答:需要怎样才能正确地停止一个运行中的线程?

    答:
    Thread类中的stop()方法因为强行终止,不能保证线程的资源正确释放已经被废弃,现在正确的停止方式是设置一个private volatile boolean flag = false;来终止线程,当flag==true时停止。即在run()方法里设置while(!flag)循环来起到终止线程的作用。

    2.4 选做:6-8(CountDownLatch)实验总结

    2.5 选做:6-9(集合同步问题)实验总结

    2.6 选做:较难:6-10(Callable),并回答为什么有Runnable了还需要Callable?实验总结。

    3. 互斥访问

    3.1 修改TestUnSynchronizedThread.java源代码使其可以同步访问。(关键代码截图,需出现学号)

    答:

    分析:
    由于在两个run()方法里,分别有调用Counter.addId();和Counter.subtractId();方法,即这两个方法为共享资源,为实现同步访问,只要在共享资源加上synchronized实现加锁即可。

    代码:

    运行结果:

    3.2 选做:进一步使用执行器改进相应代码(关键代码截图,需出现学号)

    参考资料:Java多线程之Executor、ExecutorService、Executors、Callable、Future与FutureTask

    使用Future、Callable:

    4. 互斥访问与同步访问

    完成题集6-4(互斥访问)与6-5(同步访问)

    4.1 除了使用synchronized修饰方法实现互斥同步访问,还有什么办法可以使用synchronized实现互斥同步访问,使用代码说明(请出现相关代码及学号)?

    答:
    可以用synchronized的同步代码块来实现互斥访问。

    原图:

    现在:

    4.2 同步代码块与同步方法有何区别?

    答:

    同步方法直接在方法上加synchronized实现加锁,同步代码块则在方法内部加锁,很明显,同步方法锁的范围比较大,而同步代码块范围要小点,同步的范围越大,性能就越差,需要加锁进行同步的时候,范围越小越好,这样性能更好。

    4.3 实现互斥访问的原理是什么?请使用对象锁概念并结合相应的代码块进行说明。当程序执行synchronized同步代码块或者同步方法时,线程的状态是怎么变化的?

    答:
    原理:通过给共享的资源加锁,共享资源只能允许一个线程访问。

    为了测试synchronized同步代码块或者同步方法时,线程的状态是怎么变化的,测试代码如下图:


    结果:

    分析:
    在线程1调用A后,会让线程1休眠五秒钟,这时会调用C,因为C用的是synchronized进行加锁,这里锁的对象是str这个字符串对象。而B的不同,B是用当前对象this进行加锁,又因为A直接在方法上加synchronized,显然这两个方法用的通一把锁。
    从结果看,线程1在休眠,这时锁还没释放,导致线程2只有在5秒之后才能调用方法B,所以可知两种加锁机制用的是同一个锁对象,即当前对象。

    4.4 Java多线程中使用什么关键字实现线程之间的通信,进而实现线程的协同工作?

    答:

    用wait()、notify()notifyAll()方法来协调线程之间运行关系,也可以用条件对象Condition搭配Lock对象使用。

    5. 线程间的合作:生产者消费者问题

    5.1 运行MyProducerConsumerTest.java。正常运行结果应该是仓库还剩0个货物。多运行几次,观察结果,并回答:结果正常吗?哪里不正常?为什么?



    答:
    结果不正常,每次蹦的结果不一致,并且可以发现存取后有剩余。

    原因:
    分析应该是取货时如果无法取出货物,就有消耗了一次取货的机会,并没有等待生产者的供应,那么就导致产生了剩余。

    5.2 使用synchronized, wait, notify解决该问题(关键代码截图,需出现学号)

    截图:

    结果:

    5.3 选做:使用Lock与Condition对象解决该问题。

    截图:

    结果

    6. 面向对象设计作业-图书馆管理系统

    6.1 系统的功能模块表格,表格中体现出每个模块的负责人。

    学生 负责任务
    秦玉 Library类、Menu类、User类和Uerserve类
    黄秋菊 Book类、Main类、测试类

    6.2 运行视频

    6.3 讲解自己负责的模块,并粘贴自己负责模块的关键代码(出现学号及姓名)。

    答:

    Menu类:其包含三部分内容,分别是注册,登陆,以及用户借还书的任务

    Library类:主要是书籍的加载,还有主要的peekBook方法

    Userserve类:这个类主要用来保存用户信息,这样每次注册账户时以便检索排查

    User类:这个类主要是实现用户的借还功能,并用ArrayList来存储借阅信息

    7. 选做:使用其他方法解决题目5的生产者消费者问题。

    7.1 使用BlockingQueue解决生产者消费者问题关键代码截图

    7.2 说明为什么不需要显示的使用wait、notify就可以解决同步问题。这样解决相比较wait、notify有什么优点吗?

    7.3 使用Condition解决生产者、消费者问题。

    8. 选做:编写一段代码,证明你会使用ForkJoinPool.

    9. 选做:单元测试JUint4

    实验任务书中的题目6:单元测试使用JUnit4。
    使用JUnit4对两个排序算法的排序时间进行比较,并截图。


    3.码云及PTA

    题目集:多线程

    3.1. 码云代码提交记录

    在码云的项目中,依次选择“统计-Commits历史-设置时间段”, 然后搜索并截图
    必须出现几个要素:提交日期-用户名(姓名与学号)-不提交说明

    3.2 截图"多线程"PTA提交列表

    需要有两张图(1. 排名图。2.PTA提交列表图)


    3.3 统计本周完成的代码量

    需要将每周的代码统计情况融合到一张表中。


    周次 总代码量 新增代码量 总文件数 新增文件数
    1 0 0 0 0
    2 0 0 0 0
    3 0 0 0 0
    4 0 0 0 0
    5 1167 1167 26 26
    6 1830 663 32 6
    7 2282 452 45 13
    8 2446 164 48 3
    9 2774 328 56 8
    10 3313 539 65 9
    11 3726 413 75 10
    12 4840 1114 93 18

    4. 选做:课外阅读

    4.1 Java Concurrent Animated

    4.2 线程的高级知识笔记

    4.3 Questions and Exercises: Concurrency,学习总结。

    4.4 Java多线程之Executor、ExecutorService、Executors、Callable、Future与FutureTask

    4.5 线程池,这一篇或许就够了

    4.6 Java 8 Concurrency Tutorial: Threads and Executors


    5. 选做:学会使用Eclipse进行调试

    观看相关调试视频

    5.1 简述使用Eclipse进行调试需要几步?调试时F5, F6, F7快键键各有什么不同?什么情况该使用哪个快捷键?

    5.2 实验任务书中的题目5:使用Eclipse进行调试中的5.1,如何使用Eclipse的调试功能发现当读取“蓝山兰”这行不会出错的原因?

    5.3 任务书5.2,截图证明你会使用条件断点。

    5.4 选做:调试MessageBoard.zip中的系统直至可以正常运行。说明你是怎么找到该系统中的错误?使用到了什么调试技巧?

    参考资料:Eclipse 的一些调试技巧

  • 相关阅读:
    PHP基础学习笔记(一)
    安装wampserver之后,浏览器中输入localhost页面显示IIS7解决办法
    HTML5常识总结(一)
    AngularJs中的服务
    AngularJs中的directives(指令part1)
    Happy Number——LeetCode
    Binary Tree Zigzag Level Order Traversal——LeetCode
    Construct Binary Tree from Preorder and Inorder Traversal——LeetCode
    Construct Binary Tree from Inorder and Postorder Traversal——LeetCode
    Convert Sorted Array to Binary Search Tree——LeetCode
  • 原文地址:https://www.cnblogs.com/qin-yu/p/7942581.html
Copyright © 2011-2022 走看看