20145240 《Java程序设计》第六周学习总结

教材学习内容总结

InputStream与OutputStream

10.1.1串流设计的概念
  • Java将输入/输出抽象化为串流,数据有来源及目的地,衔接两者的是串流对象。

  • 从应用程序角度来看,如果要将数据从来源取出,可以使用输入串流,如果要将数据写入目的地,可以使用输出串流。在Java中,输入串流代表对象为java.io.Inputstream实例,输出串流代表对象为java.io.OutputStream实例。

  • dump()方法接受InputStreamOutputStream实例,分别代表读取数据的来源,以及输出数据的目的地。

  • FileIntputStreamInputStream的子类,用于衔接文档以读入数据,FileOutStreamOutputStream的子类,用于衔接文档以写出数据。

  • 在不使用InputStreamOutputStream时,必须使用close()方法关闭串流。由于InputStreamOutputStrem操作了java.io.Closeable接口,其父接口为java.lang.AutoCloseable接口。

10.1.2串流继承结构
1.标准输入/输出
  • 可以使用SystemsetIn()方法指定InputStream实例,重新指定标准输入来源。

  • 可以使用SystemsetOut()方法指定```printStream````实例,将结果输出至指定的目的地。

2.FileInputStream与FileOutputStream
  • FileInputStreamInputStream的子类,可以指定文件名创建实例,一旦创建文档就开启,接着就可用来读取数据。主要操作了InputSreamread()抽象方法,可以从文档中读取数据。

  • FileOutputStreamOutputStream的子类,可以指定文件名创建实例,一旦创建文档就开启,接着就可以用来写出数据。主要操作了OnputSreamwrite()抽象方法,可以写出数据至文档。

  • 无论FileInputStream还是FileOutputStream,在读取、写入文档时是以字节为单位,通常会使用一些高阶类进行打包,不使用时都要使用close()关闭文档。

3.ByteArryInputStream与ByteArryOutputStream
  • ByteArryInputStreamInputStrteam的子类,可以指定byte数组创建实例,一旦创建就可将byte数组当做数据源进行读取。

  • ByteArryOutputStreamOutputStream的子类,可以指定byte数组创建实例,一旦创建将byte数组当做目的地写出数据。

10.1.3串流处理装饰器
  • InputStreamOutStream提供串流基本操作,如果想要为输入/输出的数据做加工处理,则可以使用打包器类。

  • 常用的打包器具备缓冲区作用的BufferedIutputStreamBufferedOnputStream,具备数据转换处理的DataInputStreamDataOutputStream,具备对象串行化能力的ObjectInputStreamObjectOutputStream等。

10.2字符处理类

10.2.1Reader与Writer继承架构
  • 针对字符数据的读取,Java SE提供了java.io.Reader类,其抽象化了字符数据读入的来源。

  • 针对字符数据的写入,则提供了java.io.Writer类。其抽象化了数据写出的目的地。

- StringReader可以将字符串打包,当作读取来源,StringWriter则可以作为写入目的地,最后用toString()取得所有写入的字符组成的字符串。

  • FileReaderFileWriter则可以对文档做读取与写入,读取或写入时默认会使用操作系统默认编码来做字符转换。

  • 在启动JVM时,可以指定-Dfile.encoding来指定FileReaderFileWriter所使用的编码。

eg:Member类可以调用save()储存Member实例本身的数据,文件名为Member的会员号码,调用Member.load()指定会员号码,则可以读取文档中的会员数据。

import java.io.IOException;
import static java.lang.System.out; public class MemberDemo {
public static void main(String[] args) throws IOException {
Member[] members = {
new Member("B1234", "Justin", 90),
new Member("B5678", "Monica", 95),
new Member("B9876", "Irene", 88)
};
for(Member member : members) {
member.save();
}
out.println(Member.load("B1234"));
out.println(Member.load("B5678"));
out.println(Member.load("B9876"));
}
}
  • 运行结果

10.2.2字符处理装饰器
1.InputStreamReader与OutputStreamWriter
  • InputStreamReaderOutputStreamWriter对串流数据打包。
2.BufferedReader与BufferedWriter
  • BufferedReaderBufferedWriter可对ReaderWriter提供缓冲区作用,在处理字符输入/输出时,对效率也会有所帮助。
3.PrintWriter
  • PrintWriterPrintStream使用上极为类似,不过除了可以对OutputStream打包之外,PrintWriter还可以对Writer进行打包,提供print()、println()、format()等方法。

11.1线程

11.1.1线程简介
  • 在java中,如果想在main()以外独立设计流程,可以撰写类操作java.lang.Runnable接口,流程的进入点是操作在run()方法中。

  • 在java中,从main()开始的流程会由主线程执行,可以创建Thread实例来执行Runnable实例定义的run()方法。

eg:TortoiseHareRace2.java。

  • 运行结果

10.1.2Thread与Runnable
  • JVM是台虚拟计算机,只安装一颗称为主线程的CPU,可执行main()定义的执行流程。如果想要为JVM加装CPU,就是创建Thread实例,要启动额外CPU就是调用Thread实例的start()方法,额外CPU执行流程的进入点,可以定义在Runnale接口的run()方法中。

  • 撰写多线程程序的方式:

    1.将流程定义在Runnablerun()方法中。

    2.继承Thread类,重新定义run()方法。

  • 操作Runnable接口的好处就是较有弹性,你的类还有机会继承其他类。若继承了Thread,那该类就是一种Thread,通常是为了直接利用Thread中定义的一些方法,才会继承Thread来操作。

11.1.3线程生命周期
1.Daemon线程
  • 主线程会从main()方法开始执行,直到main()方法结束后停止JVM。

  • 如果主线程中启动了额外线程,默认会等待被启动的所有线程都执行完run()方法才中止JVM。

  • setDeamon()方法用来设定一个线程是否为Daemon线程。

  • 如果没有使用setDeamon()设定为true,则程序会不断的输出Orz而不终止。

  • isDaemon()方法可以判断线程是否为Daemon线程。

  • 运行结果

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

eg:DaemonDemo.java。

  • 运行结果

eg:若不使用setDeamon()方法。

  • 运行结果

3.安插线程
  • 当线程使用join()加入至另一个线程时,另一个线程会等待被加入的线程工作完毕,然后在继续它的动作,join()的意思表示将线程加入称为另一个线程的流程中。
4.停止线程
  • 线程完成run()方法后,就会进入Dead,进入Dead的线程不可以再次调用start()方法,否则会抛出IllegalThreadStateException

eg:InterruptedDemo.java。

  • 运行结果

11.1.4关于ThreadGroup
  • 获取目前线程所属线程群组名:Thread.currentThread().getThreadGroup().getName()

  • ThreadGroup的某些方法,可以对群组中所有线程产生作用。interrupt()方法可以中断群组中所有线程,setMaxPriority()方法可以设定群组中所有线程最大优先权。activeCount()方法获取群组的线程数量 。

  • 未捕捉异常会由线程实例setUncaughtExceptionHandler()设定的Thread.UncaughtExceptionHandler实例处理之后是线程ThreadGroup,然后是默认的Thread.UncaughtExceptionHandler

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

  • java的synchronize提供的是可重入同步,也就是线程取得某对象锁定后,若执行过程总又要执行synchronize,尝试取得锁定的对象来源又是同一个,则可以直接执行。

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

eg:ThreadGroupDemo2.java。

  • 运行结果

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

  • 可以在变量上声明volatile,标示变量是不稳定、易变的,也就是可能在多线程下存取,这保证变量的可见性,也就是若有线程变动了变量值,另一线程一定可看到变更。被标示为volatile的变量,不允许线程快取,变量值的存取一定是在共享内存中进行。

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

eg:Variable2Test.java。

  • 运行结果

eg:Variable3Test.java。

  • 运行结果

11.1.6等待与通知
  • wait()、notify()、notifyAll()Object定义的方法,可以通过这3个方法控制线程释放对象的锁定,或者通知线程参与锁定竞争。

  • 线程要进入synchronized范围前,要先取得指定对象的锁定。执行synchronized范围的程序代码期间,若调用锁定对象的wait()方法,线程会释放对象锁定,并进入对象等待集合而处于阻断状态。

  • 放在等待集合的线程不会参与CPU排班,wait()可以指定等待时间,时间到之后线程会再次加入排班,如果指定时间0或不指定,则线程会持续等待,知道被中断或是告知可以参与排班。

  • wait()一定要在条件式成立的循环中执行。

11.2并行API

11.2.1Lock、ReadWriteLock与Condition
1.使用Lock
  • lock接口主要操作类之一为ReentrantLock,可以达到synchronized的作用。

  • 想要锁定Lock对象,可以调用其lock()方法,只有取得Lock对象锁定的线程才可以继续往后执行程序代码,要解除锁定可以调用Lock对象的unclock()

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

2.使用ReadWriteLock
  • ReadWriteLock接口定义了读取锁定与写入锁定行为,可以使用readLock()、`writeLock()方法返回Lock```操作对象。

  • ReentrantReadWriteLockReadWriteLock接口的主要操作类,readLock()方法会返回ReentrantReadWriteLock.ReadLock实例,writeLock()犯法会返回ReentrantReadWriteLock.WriteLock实例。

3.使用StampedLock
  • StampedLock类可支持了乐观读取操作。也就是若读取线程很多,写入线程很少的情况下,你可以乐观地认为,写入与读取同时发生的机会很少,因此不悲观的使用哇暖的读取锁定,程序可以查看数据读取之后,是否遭到写入线程的变更,再采取后续的措施。
4.使用Condition
  • Condition接口用来搭配Lock,最基本用法就是达到Object的wait()、notify()、notifyAll()方法的作用。

  • Conditionawait()、signal()、signalAll()方法,可视为Object的wait()、notify()、notifyAll()方法的对应。

11.2.2使用Executor
  • Runnable用来定义可执行流程与可使用数据,Thread用来执行Runnable
  • Runnable指定给Thread创建之用,并调用start()开始执行。
  • 定义了java.util.concurrent.Executor接口,目的是将Runnable指定与实际执行分离。

eg:FutureCallableDemo.java。

  • 运行结果

1.使用ThreadPoolExecutor
  • 线程池这类服务的行为实际上是定义在Executor的子接口java.util.concurrent.ExecutorService中。
  • 通用的java.util.concurrent.ExecutornewCacheThreadPool()newFixedThreadPool()静态方法来创建ThreadPoolExecutor实例,程序看起来较为清楚且方便。
2.使用ScheduledThreadPoolExecutor
  • ScheduledExecutorServiceExecutorService的子接口,顾名思义,可以让你进行工作排程。
  • schedule()方法用来排定RunnableCallable实例延迟多久后执行一次,并返回Future子接口ScheduledFuture的实例。
  • 对于重复性的执行,可使用scheduleWithFixedDelay()scheduleAtFixedRate()方法。
3.使用ForkJoinPool
  • ForkJoinPool与其他的ExecutorService操作不同的地方在于,它是闲聊了工作窃取演算,其建立的线程如果完成手边任务,会尝试寻找并执行其他任务建立的资额任务,让线程保持忙碌状态,有效利用处理器的能力。
  • ForkJoin框架适用于计算密集式的任务,较不适合用于容易造成线程阻断的场合。
11.2.3并行Collection简介
  • CopyOnWriteArrayList操作了List接口,这个类的实例在写入操作时,内部会建立新数组,并复制原有数组索引的参考,然后在新数组上进行写入操作,写入完成后,再将内部原参考旧数组的变量参考至新数组。

  • CopyOnWriteArraySet操作了Set接口,与CopyOnWriteArrayList相似。

  • BlockedQueueQueue的子接口,新定义了put()、take()方法。

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

  • ConcurrentHashMapConcurrentMap的操作类,ConcurrentNavigableMapConcurrentMap的子接口,其操作类为ConcurrentSkipListMap,可视为支持并行操作的TreeMap版本。

本周代码托管截图







学习进度条

代码行数(新增/累积) 博客量(新增/累积) 学习时间(新增/累积) 重要成长
目标 5000行 30篇 400小时
第一周 200/200 1/2 20/20
第二周 300/500 1/3 30/50
第三周 500/1000 1/4 35/85
第四周 1225/2225 1/5 40/125
第五周 993/3218 1/5 35/160
第六周 1360/4578 2/7 40/200

20145240 《Java程序设计》第六周学习总结的更多相关文章

  1. 20145240 《Java程序设计》第九周学习总结

    20145240 <Java程序设计>第九周学习总结 教材学习内容总结 JBDC是用于执行SQL的解决方案,开发人员使用JDBC的标准接口,数据库厂商对接口直接操作,开发人员无须接触底层数 ...

  2. 20145240《Java程序设计》第二周学习总结

    20145240 <Java程序设计>第二周学习总结 教材学习内容总结 本周主要学习了第三章的内容,讲的是Java的一些基础语法,包括两大系统类型.变量.运算符的基本使用.类型转换及几个基 ...

  3. 20145240《Java程序设计》第一周学习总结

    20145240 <Java程序设计>第一周学习总结 教材学习内容总结 第一周学习Java首先从最基本的下载.配置环境.了解基本人机命令行方式等基础知识,以及编写简单的"Hell ...

  4. 20145213《Java程序设计》第九周学习总结

    20145213<Java程序设计>第九周学习总结 教材学习总结 "五一"假期过得太快,就像龙卷风.没有一点点防备,就与Java博客撞个满怀.在这个普天同庆的节日里,根 ...

  5. 21045308刘昊阳 《Java程序设计》第九周学习总结

    21045308刘昊阳 <Java程序设计>第九周学习总结 教材学习内容总结 第16章 整合数据库 16.1 JDBC入门 16.1.1 JDBC简介 数据库本身是个独立运行的应用程序 撰 ...

  6. 《Java程序设计》第九周学习总结

    20145224 <Java程序设计>第九周学习总结 第十六章 整合数据库 JDBC入门 ·数据库本身是个独立运行的应用程序 ·撰写应用程序是利用通信协议对数据库进行指令交换,以进行数据的 ...

  7. 20145236 《Java程序设计》第九周学习总结

    20145236 <Java程序设计>第九周学习总结 教材学习内容总结 第十六章 整合数据库 JDBC简介 1.JDBC是java联机数据库的标准规范.它定义了一组标准类与接口,标准API ...

  8. 20155304田宜楠2006-2007-2 《Java程序设计》第一周学习总结

    20155304田宜楠2006-2007-2 <Java程序设计>第一周学习总结 教材学习内容总结 - 浏览教材,根据自己的理解每章提出一个问题 第一章 除了书上提到的开发工具还有什么适合 ...

  9. 20155303 2016-2017-2 《Java程序设计》第二周学习总结

    20155303 2016-2017-2 <Java程序设计>第二周学习总结 教材学习内容总结 『注意』 "//"为单行批注符: "/*"与&quo ...

  10. 20145237 《Java程序设计》第九周学习总结

    20145237 <Java程序设计>第九周学习总结 教材学习内容总结 第十六章 整合数据库 JDBC入门 ·数据库本身是个独立运行的应用程序 ·撰写应用程序是利用通信协议对数据库进行指令 ...

随机推荐

  1. 任何应用程序都可拥有 Web Service 组件。

    任何应用程序都可拥有 Web Service 组件. Web Service 的创建与编程语言的种类无关. 本章节我们将为大家介绍使用 PHP 的 SOAP 扩展来创建 Web Service. SO ...

  2. In the shell, what does “ 2>&1 ” mean?

    In a Unix shell, if I want to combine stderr and stdout into the stdout stream for further manipulat ...

  3. day23面向对象第一篇

      python之路——初识面向对象   阅读目录 楔子 面向过程vs面向对象 初识面向对象 类的相关知识 对象的相关知识 对象之间的交互 类命名空间与对象.实例的命名空间 类的组合用法 初识面向对象 ...

  4. 七个迹象说明你可能受到APT 攻击

    watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaXF1c2hp/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/d ...

  5. eval()和exec()函数的区别

    (1)eval(str [,globals [,locals ])函数将字符串str当成有效Python表达式来求值,并返回计算结果.(2)exec()函数将字符串str当成有效的Python表达式来 ...

  6. 微信小程序开发遇见的问题之一

    在开发的时候,因为要定位到当前的城市,而小程序提供的API只是能够获取当前的经纬度,所以我们需要通过接入百度地图的API.调接口的时候发现报错,说域名不合法,此时千万不要着急,只要你登录你的微信开发公 ...

  7. Kubectl工具常用命令

    创建namesapce kubectl create namespace {name} 注意:name只能为小写字母.数字和-的组合,且开头结尾为字母,一般格式为my-name 123-abc等. 创 ...

  8. xenserver 模板导出导入

    由于业务需求,新增一台xenserver,需要将原先创建好的模板环境导入到新的母机上面,此处记录一下 1.导出模板 # 获取需要导出的模板uuid [root@localhost ~]# xe tem ...

  9. 【转】虚拟 IO 服务器(VIOS)和 IBM i

    Power 主机上的虚拟化应用,简单阐述虚拟 IO 服务器的功能,用途,优点,以及虚拟 IO 服务器在高级虚拟化技术的作用.举例说明虚拟 IO 服务器与 IBM i 分区直接互联特性. 引言 随着信息 ...

  10. python的文件处理学习笔记

    python的文件处理函数是open() 以下主要是关于这个函数的一些学习笔记 1.文件处理离不开编码 要注意的是文件打开时的编码和文件保存时的编码的统一,这样才能保证你打开的文件不会存在乱码 总结: ...