zoukankan      html  css  js  c++  java
  • 20155219 2016-2017-2 《Java程序设计》第6周学习总结

    20155219 2016-2017-2 《Java程序设计》第6周学习总结

    教材学习内容总结

    串流设计

    image
    1.串流:Java将输入/输出抽象化为串流,数据有来源及目的地,衔接两者的是串流对象。

    2.将数据从来源取出,可以使用输入串流,代表对象为java.io.Inputstream实例;将数据写入目的地,可以使用输出串流,代表对象为java.io.OutputStream实例。

    3.在进行InputStream与OutStream的相关操作时若发生错误,会抛出java.io.IOException异常,在dump()方法上声明throws,由调用dump()方法的客户端处理。

    4.在不使用InputStream与OutputStream时,必须使用close()方法关闭串流。

    5.流(Stream)是对「输入输出」的抽象,注意「输入输出」是相对程序而言的
    InputStream与OutputStream,
    InputStream、OutStream提供串流基本操作,如果想要为输入/输出的数据做加工处理,则可以使用打包器类。

    6.常用的打包器具备缓冲区作用的BufferedOutputStream、BufferedInputStream,具备数据转换处理的DataInputStream、DataOutputStream,具备对象串行化能力的ObjectInputStream、ObjectOutputStream等。

    7.针对字符数据的读取,Java SE提供了java.io.Reader类,其抽象化了字符数据读入的来源。针对字符数据的写入,则提供了java.io.Writer类。其抽象化了数据写出的目的地。

    8.FileReader、FileWriter则可以对文档做读取与写入,读取或写入时默认会使用操作系统默认编码来做字符转换。在启动JVM时,可以指定-Dfile.encoding来指定FileReader、FileWriter所使用的编码。

    装饰器类

    • Decorator模式
      BufferedInputStream与BufferedOutputStream: 内部提供缓冲,提高效率
    • DataInputStream与DataOutputStream:基本数据类型与字节的转换。
    • ObjectInputStream与ObjectOutputStream的java.io.Serializable接口。

    字符处理类

    • Reader、Writer也有一些装饰器类可供使用。如果串流处理的字节数据,实际上代表某些字符的编码数据,而你想要将这些字节数据转换为对应的编码字符,可以使用InputStreamReader、OutputStreamWriter对串流数据打包。BufferedReader、BufferedWriter可对Reader、Writer提供缓冲区作用,在处理字符输入/输出时,对效率也会有所帮助。PrintReader、PrintStream使用上极为类似,不过除了可以对OutputStream打包之外,PrintWriter还可以对Writer进行打包,提供print()、println()、format()等方法。

    字符处理装饰器

    • 想要将这些字节数据转换为对应的编码字符,可以使用InputStreamReader、OutputStreamWriter对串流数据打包。
      BufferedReader、BufferedWriter可对Reader、Writer提供缓冲区作用,在处理字符输入/输出时,对效率也会有所帮助。
      PrintWriter还可以对Writer进行打包,提供print()、println()、format()等方法。

    线程

    1.多线程程序即程序拥有多个流程。

    2.在main()以外独立设计流程,可以撰写类操作java.lang.Runnable接口,流程的进入点是操作在run()方法中。从main()开始的流程会由主线程执行,run()方法可以创建Thread实例来执行。启动额外线程执行指定流程,必须调用Thread实例的start()方法。

    线程生命周期

    1.Daemon线程:主线程会从main()方法开始执行,直到main()方法结束后停止JVM。如果主线程中启动了额外线程,默认会等待被启动的所有线程都执行完run()方法才中止JVM。 如果一个Thread被标示为Daemon线程,在所有的非Daemon线程都结束时,JVM自动就会终止。

    2.Thread基本状态图:用Thread实例start()方法后,基本状态为可执行(Runnable)、被阻断(Blocked)、执行中(Running)。

    3.安插线程:join()表示将线程加入称为另一个线程的流程中,线程使用join()加入至另一个线程时,另一个线程会等待被加入的线程工作完毕,然后在继续它的动作。

    4.停止线程:线程完成run()方法后,就会进入Dead,进入Dead的线程不可以再次调用start()方法,否则会抛出IllegalThreadStateException异常。

    关于ThreadGroup

    1.java.lang.ThreadGroup类可以管理群组中的线程。interrupt()方法可以中断群组中所有线程;setMaxPriority()方法可以设定群组中所有线程最大优先权;activeCount()方法可以获取群组的线程数量 ;enumerate()方法可以一次取得群组中所有线程;uncaughtException()方法第一个参数可取得发生异常的线程实例,第二个参数可取得异常对象。

    synchronized与volatile

    1.不具备线程安全的类:线程存取同一对象相同资源时可能引起竞速情况的类。

    2.使用synchronized

    每个对象都会有个内部锁定,或称为监控锁定。被标示为synchronized的区块将会被监控,任何线程要执行synchronize区块都必须先取得指定的对象锁定。

    线程无法取得锁定时会造成阻断,不正确地使用synchronize有可能造成效能低下,另一个问题则是死结。

    synchronized要求达到的所标示区域的互斥性和可见性。互斥性是指synchronized区块同时间只能有一个线程;可见性是指线程离开synchronized区块后,另一线程接触到的就是上一线程改变后的对象状态。

    3.使用volatile

    在变量上声明volatile,标示变量是不稳定、易变的,也就是可能在多线程下存取。被标示为volatile的变量,不允许线程快取,变量值的存取一定是在共享内存中进行。

    volatile保证的是单一变数的可见性,线程对变量的存取一定是在共享内存中,不会在自己的内存空间中快取变量,线程对共享内存中变量的存取,另一线程一定看得到。

    等待与通知

    1.调用锁定对象的wait()方法:线程会释放对象锁定,并进入对象等待集合而处于阻断状态,其他线程可以竞争对象锁定,取得锁定的线程可以执行synchronize区块的代码。

    2.调用锁定对象的notify()方法:从对象等待集合中随机通知一个线程加入排班,再次执行synchronize前,被通知的其他线程共同竞争对象锁定。

    3.调用锁定对象的notifyAll()方法:所有等待集合中的线程都会被通知参与排班,这些线程会与其他线程共同竞争对象锁定。

    并行API

    Lock、ReadWriteLock与Condition

    1.使用Lock

    lock接口主要操作类之一为ReentrantLock,如果已经有线程取得Lock对象锁定,尝试在一次锁定同一Lock对象是可以的。

    Lock接口还定义了tryLock()方法,如果线程调用tryLock()可以取得锁定会返回true,若无法取得锁定并不会发生阻断,而是返回false。

    2.ReadWriteLock

    ReadWriteLock接口定义了读取锁定与写入锁定行为,ReentrantReadWriteLock是ReadWriteLock接口的主要操作类,readLock()方法会返回ReentrantReadWriteLock.ReadLock实例,writeLock()犯法会返回ReentrantReadWriteLock.WriteLock实例。

    3.使用StampedLock

    支持乐观读取操作。在读取线程很多,写入线程很少的情况下,程序可以查看数据读取之后是否遭到写入线程的变更,再采取后续的措施。

    4.使用Condition

    Condition接口用来搭配Lock,Condition的await()、signal()、signalAll()方法,可视为Object的wait()、notify()、notifyAll()方法的对应。

    使用Executor

    1.使用ThreadPoolExecutor:线程池这类服务的行为实际上是定义在Executor的子接口java.util.concurrent.ExecutorService中,通常会使用java.util.concurrent.Executor的newCacheThreadPool()、newFixedThreadPool()静态方法来创建ThreadPoolExecutor实例,程序看起来较为清楚且方便。

    2.使用ScheduledThreadPoolExecutor:ScheduledExecutorService为ExecutorService的子接口,可以让你进行工作排程。schedule()方法用来排定Runnable或Callable实例延迟多久后执行一次,并返回Future子接口ScheduledFuture的实例,对于重复性的执行,可使用scheduleWithFixedDelay()和scheduleAtFixedRate()方法。

    3.使用ForkJoinPool:ForkJoinPool闲聊了工作窃取演算,其建立的线程如果完成手边任务,会尝试寻找并执行其他任务建立的资额任务,让线程保持忙碌状态,有效利用处理器的能力。ForkJoin框架适用于计算密集式的任务,较不适合用于容易造成线程阻断的场合。

    并行Collection简介

    1.CopyOnWriteArrayList操作了List接口,这个类的实例在写入操作时,内部会建立新数组,并复制原有数组索引的参考,然后在新数组上进行写入操作,写入完成后,再将内部原参考旧数组的变量参考至新数组。

    2.CopyOnWriteArraySet操作了Set接口,内部特性与CopyOnWriteArrayList相似。

    3.BlockedQueue是Queue的子接口,新定义了put()、take()方法。

    4.ConcurrentMap是Map的子接口,其定义了putIfAbsent()、remove()、replace()等方法。这些方法都是原子操作。

    5.ConcurrentHashMap是ConcurrentMap的操作类,ConcurrentNavigableMap是ConcurrentMap的子接口,其操作类为ConcurrentSkipListMap,可视为支持并行操作的TreeMap版本。

    教材学习中的问题和解决过程

    • 问题1:书中代码如下:
    
    public class DaemonDemo {
    
        public static void main(String[] args) {
            Thread thread = new Thread(() -> {
                while (true) {
                    System.out.println("Orz");
                }
            });
            // thread.setDaemon(true);
            thread.start();
        }
    }
    
    

    不理解setdemo()的作用,心想既然setdemo(true)了,那对于语句

    while (true) {
                    System.out.println("Orz");
                }
    

    应该无限循环才对,而不是删去语句后才无限循环输出orz。

    • 解决方案:查找API,和上网百度。知道了setDaemon方法是Thread中的方法,默认为false状态,将该线程标记为守护线程或用户线程,该方法必须在启动线程前调用,具有最低的优先级,让系统资源优先调用其他线程。当正在运行的线程都是守护线程时,Java 虚拟机退出。线程setDaemon(true)就是将当前进程变成后台进程。如果对某个线程对象在启动(调用start方法)之前调用了setDaemon(true)方法,这个线程就变成了后台线程.对java程序来说,只要还有一个前台线程在运行,这个进程就不会结束,如果一个进程中只有后台线程运行,这个进程会结束.必须在启动线程前调用。
      故对于上述代码,如果是thread.setDaemon(true);则表示把这个线程归为守护线程,如果所有非守护线程全部运行完之后,守护线程自动关闭。如果是thread.setDaemon(false)则是永无止境的循环。
    • xx2问题:书上P335页joindemo.java,在解释为什么 最后一行会显示“Main thread将结束...”时说:因为thread使用了sleep(),这让主线程有机会取得时间去执行。但不清楚sleep方法用在了那里。
    • xx2解决方案
    • 问题3:Throwable、Error、Exception、RuntimeException 区别 联系。
    • 解决方案:Throwable 类是 Java 语言中所有错误或异常的超类。它的两个子类是Error和Exception。ThreadDeath 错误是一个“正规”的条件,但它也是 Error 的子类。

    代码调试中的问题和解决过程

    • 问题一:
      教材327页TortoiseHareRace2.java代码运行结果如下:
      image
      并没有运行出书上的结果。
    • xx1解决方案:将代码修改为:
    w b=new w(10);
            vv a=new vv(10);
            int totalStep=10;
            while(a.x()<totalStep&&b.x()<totalStep)
            {
                Thread tortoiseThread = new Thread(a);
                Thread hareThread = new Thread(b);
                tortoiseThread.start();
                hareThread.start();
    
    

    运行结果如下:
    image

    • xx2问题
    • xx2解决方案
    • ...

    代码托管

    • 代码提交过程截图:
      • 运行 git log --pretty=format:"%h - %an, %cd : %s" 并截图
    • 代码量截图:
      • 运行 find src -name "*.java" | xargs cat | grep -v ^$ | wc -l 并截图image

    上周考试错题总结

    • 错题1:
     class Number{
        2.     public static void main(String  []  args)  {
        3.    try  {
        4.          System.out.print (Integer.parselnt ("forty"));
        5.      } catch (RuntimeException r)  {
        6.           System.out.print ("runtime");
        7.       } catch  (NumberFormatException e)  {
        8.           System.out.print("number");
        9.     }
        10.    }
        11.  }
    

    应该是编译失败,因为RuntimeException是NumberFormatException的父类,如果先catch了RuntimeException e那么NumberFormatException e就永远不会被执行了。应该先catch子类,后catch父类。

    • 错题2:下列属于非受检异常的是哪项?
      :

    A.SQLException
    B.IOException
    C.NullPointerException
    D.OutOfMemoryError
    答案:D
    异常分为受检异常与非受检异常,OutOfMemoryError属于Error为非受检异常

    • 错题3:
    import java.util.*;class ForInTest  {
    static List list=new ArrayList();
    
             public static void main (String  []  args)  {
        list. add("a"); list. add("b");list. add( "c");
       //insert code here
        System.out.print (o);
          }
          }
        哪一行插入到第9行将导致输出“abc"?
    
                :
                A	.
                for (Iterator o  :  list.iterator();  o.hasNext  ();  )
    
                B	.
                for (Iterator o :  list)
    
                C	.
                for (Object o  :  list.iterator())
    
                D	.
                for (Object o  :  list)
    

    答案是d,运用了增强式for循环

    结对及互评

    点评过的同学博客和代码

    • 本周结对学习情况
      • 20155224
      • 结对照片image
      • 结对学习内容
        • 上周错题的理解与掌握。
        • 第十章与第十一章教材学习中遇到的问题进行讨论。
        • 第十章与第十一章代码调试中遇到的问题进行讨论。
    • 上周博客互评情况

    学习进度条

    代码行数(新增/累积) 博客量(新增/累积) 学习时间(新增/累积) 重要成长
    目标 5000行 30篇 400小时
    第一周 120/120 1/4 16/16 开始了JAVA学习的第一步!
    第二周 346/466 1/5 23/36 了解并学习了Java基础语法
    第三周 364/830 1/6 21/57 进一步了解java设计语句
    第四周 570/1300 2/8 20/77 初步学习了继承与多态,接口与多态知识。
    第五周 1056/2356 1/9 23/100 了解Java的异常处理,学习Collection和Map架构
    第六周 960/3100 1/10 22/122 了解串流设计和线程

    尝试一下记录「计划学习时间」和「实际学习时间」,到期末看看能不能改进自己的计划能力。这个工作学习中很重要,也很有用。
    耗时估计的公式
    :Y=X+X/N ,Y=X-X/N,训练次数多了,X、Y就接近了。

    参考:软件工程软件的估计为什么这么难软件工程 估计方法

    参考资料

  • 相关阅读:
    Java RunTime Environment (JRE) or Java Development Kit (JDK) must be available in order to run Eclipse. ......
    UVA 1597 Searching the Web
    UVA 1596 Bug Hunt
    UVA 230 Borrowers
    UVA 221 Urban Elevations
    UVA 814 The Letter Carrier's Rounds
    UVA 207 PGA Tour Prize Money
    UVA 1592 Database
    UVA 540 Team Queue
    UVA 12096 The SetStack Computer
  • 原文地址:https://www.cnblogs.com/paypay/p/6654708.html
Copyright © 2011-2022 走看看