20145232 韩文浩 《Java程序设计》第6周学习总结
2016-04-10 18:54
441 查看
教材学习内容总结
Java是以串流(Stream)的方式来处理输入与输出。串流是一种抽象观念,从键盘输入资料,将处理结果输入档案,以及读取档案的内容等动作皆视为串流的处理。
输入串流代表对象为
java.io.InputStream实例,输出串流代表对象
java.io.OutputStream实例。
在不使用InputStream与OutputStream时,必须使用
close()方法关闭串流。
System.in与System.out分别是InputStream与PrintStream的实例,标准输入与标准输出。
FileInputStream是InputStream的子类,可以指定文件名创建实例,一旦创建文档就开启,接着就可以用来读取数据,FileOutputStream是OutputStream的子类,可以指定文件名创建实例,一旦创建文档就开启,接着就可以用来写出数据,无论FileInputStream还是FileOutputStream,不使用时都要用
close()关闭文档。
在启用JVM时,可以指定-Dfile.encoding来指定FileReader、FileWriter所使用的编码
> java -Dfile.encoding=UTF-8 cc.openhome.CharUtil sample.txt
BufferedInputStream与BufferedOutputStream提供的是前面描述的缓冲区功能。
ByteArrayInputStream是InputStream的子类,可指定byte数组创建实例。一旦创建就可以将byte数组当作数据源进行读取。ByteArrayOutputStream是OutputStream的子类,可指定byte数组创建实例。一旦创建就可以将byte数组当作目的地写出数据。
字符数据的读取,java SE提供了java.io.reader类。
字符数据的写入则提供了java.io.writer类。
使用InputStreamReader和OutputstreamWriter可对串流数据打包。
在java中,如果想在main()以外独立设计流程,可以撰写类操作java.lang.Runnable接口,流程的进入点是操作在run()方法中。
撰写多线程程序的方式:将流程定义在Runnable的run()方法中 / 继承Thread类,重新定义run()方法
在java中,从main()开始的流程会由主线程执行,可以创建Thread实例来执行Runnable实例定义的run()方法。
Thread与Runnable:从抽象观点与开发者的角度来看,JVM是台虚拟计算机,只安装了一颗称为主线程的CPU,可执行main()定义的执行流程。如果想要为JVM加装CPU,就是创建Thread实例,要启动额外CPU就是调用Thread实例的start()方法,额外CPU执行流程的进入点,可以定义在Runnable接口的run()方法中。除了将流程定义在Runnable的run()方法中,另一个撰写多线程程序的方式,就是继承Thread类,重新定义run()方法。操作Runnable接口的好处就是较有弹性,你的类还有机会继承其他类。若继承了Thread,那该类就是一种Thread,通常是为了直接利用Thread中定义的一些方法,才会继承Thread来操作。
要让目前流程暂停指定时间,可以使用java.lang.Thread的静态sleep()方法。
在调用Thread实例start()方法后,基本状态为可执行,被阻断,执行中。
thread类上定义有stop()方法,被标示为Deprecated。
每个线程都属于某个线程群组。在java中要想实现多线程,有两种手段,一种是继续Thread类,另外一种是实现Runable接口。
每个对象都会有个内部锁定,称为监控锁定。
lock接口主要操作类之一为ReentrantLock,可以达到synchronized的作用。
为了避免调用Lock()后,在后续执行流程中抛出异常而无法解除锁定,一定要在finally中调用Lock对象的unlock()方法。 Lock接口还定义了tryLock()方法,如果线程调用tryLock()可以取得锁定会返回true,若无法取得锁定并不会发生阻断,而是返回false。
ReadWriteLock接口定义了读取锁定与写入锁定行为,可以使用readLock()、writeLock()方法返回Lock操作对象。ReentrantReadWriteLock是ReadWriteLock接口的主要操作类,readLock()方法会返回ReentrantReadWriteLock.ReadLock实例,writeLock()犯法会返回ReentrantReadWriteLock.WriteLock实例。
StampedLock类可支持了乐观读取操作。也就是若读取线程很多,写入线程很少的情况下,你可以乐观地认为,写入与读取同时发生的机会很少,因此不悲观的使用哇暖的读取锁定,程序可以查看数据读取之后,是否遭到写入线程的变更,再采取后续的措施。
Condition接口用来搭配Lock,最基本用法就是达到Object的wait()、notify()、notifyAll()方法的作用。Condition的await()、signal()、signalAll()方法,可视为Object的wait()、notify()、notifyAll()方法的对应。
使用Lock:lock接口主要操作类之一为ReentrantLock,可以达到synchronized的作用,也提供额外的功能。
使用ReadWriteLock:ReadWriteLock接口定义了读取锁定与写入锁定行为,可以使用readLock()、writeLock()方法返回Lock操作对象。ReentrantReadWriteLock是ReadWriteLock接口的主要操作类,readLock()方法会返回ReentrantReadWriteLock.ReadLock实例,writeLock()犯法会返回ReentrantReadWriteLock.WriteLock实例。
使用StampedLock:JDK8新增了StampedLock类,可支持乐观读取操作。也就是若读取线程很多,写入线程很少的情况下,你可以乐观地认为,写入与读取同时发生的机会很少,因此不悲观的使用哇暖的读取锁定,程序可以查看数据读取之后,是否遭到写入线程的变更,再采取后续的措施。
使用Condition:Condition接口用来搭配Lock,最基本用法就是达到Object的wait()、notify()、notifyAll()方法的作用。
使用CharUtil.dump读入文档、转为字符串并显示在文本模式下:
import java.io.*; public class CharUtilDemo { public static void main(String[] args) throws IOException { FileReader reader = new FileReader(args[0]); StringWriter writer = new StringWriter(); CharUtil.dump(reader, writer); System.out.println(writer.toString()); } }
在命令行自变量指定了文档位置,若文档中实际都是字符数据,就可以在文档模式中看到文档中的文字内容。
如果串流处理的字节数据,实际上代表某些字符的编码数据,而你想要将这些字节数据转换为对应的编码字符,可以使用InputStreamReader、OutputStreamWriter对串流数据打包,在建立InputStreamReader与OutputStreamWriter时,可以指定编码,如果没有指定编码,则以JVM启动时所获取的默认编码来做字符转换。PrintStream与PrintWriter使用上极为相似,不过除了可以对OutputStream打包之外,PrintWriter还可以对Writer进行打包,提供print()、println()、format()等方法。
关于ThreadGroup
java.lang.ThreadGroup类正如其名,可以管理群组中的线程。
interrupt()方法可以中断群组中所有线程。
setMaxPriority()方法可以设定群组中所有线程最大优先权。
activeCount()方法取得群组的线程数量,eunmerate()方法要传入Thread数组,这会将线程对象设定至每个数组索引。
public class ThreadGroupDemo { public static void main(String[] args) { ThreadGroup group = new ThreadGroup("group") { @Override public void uncaughtException(Thread thread, Throwable throwable) { System.out.printf("%s: %s%n", thread.getName(), throwable.getMessage()); } }; Thread thread = new Thread(group, () -> { throw new RuntimeException("测试异常"); }); thread.start(); } }
uncaughException()方法第一个参数可取得发生异常的线程实例,第二个参数可取得异常对象,范例中
显示了线程的名称及异常信息
public class ThreadGroupDemo2 { public static void main(String[] args) { ThreadGroup group = new ThreadGroup("group"); Thread thread1 = new Thread(group, () -> { throw new RuntimeException("thread1 测试例外"); }); thread1.setUncaughtExceptionHandler((thread, throwable) -> { System.out.printf("%s: %s%n", thread.getName(), throwable.getMessage()); }); Thread thread2 = new Thread(group, () -> { throw new RuntimeException("thread2 测试异常"); }); thread1.start(); thread2.start(); } }
每个线程都属于某个线程群组,如果没有指定,则归入产生该子线程的线程群组,也可以自行指定线程群组,线程一旦归入某个群组,就无法再更换。ThreadGroup的某些方法,可以对群组中所有线程产生作用。如果想要一次取得群组中所有线程,可以使用enumerate()方法。activeCount()方法取得群组的线程数量。
教材学习中的问题和解决过程
InputStream、Reader与Writer区别,还是有些模糊Reader:用于读取字符流的抽象类。子类必须实现的方法只有 read(char[], int, int) 和 close()。
Writer:写入字符流的抽象类。子类必须实现的方法仅有 write(char[], int, int)、flush() 和 close()。
Reader和Writer都属于字符流。
InputStream属于字节流。
InputStream:是表示字节输入流的所有类的超类。
本周代码托管截图
其他(感悟、思考等,可选)
这周的概念也有不少,看起来还是比较费力,学习了输入输出,线程与并行API,所以不能一股脑全看完,这样不仅没印象而且还浪费不少时间,主要还是结合书上的代码,积极主动敲代码,主动发现问题。关于书上介绍的一些API,还有一些格式,他们的架构是怎样的,这些都需要不断巩固总结。学习进度条
代码行数(新增/累积) | 博客量(新增/累积) | 学习时间(新增/累积) | 重要成长 | |
---|---|---|---|---|
目标 | 4000行 | 16篇 | 400小时 | |
第一周 | 200/200 | 2/2 | 20/20 | |
第二周 | 300/500 | 1/3 | 25/45 | |
第三周 | 500/1000 | 1/4 | 40/85 | |
第四周 | 800/1800 | 1/5 | 45/130 | |
第五周 | 700/2500 | 1/6 | 43/173 | |
第六周 | 700/3200 | 1/7 | 48/221 |
参考资料
Java学习笔记(第8版)《Java学习笔记(第8版)》学习指导
相关文章推荐
- Eclipse将引用了第三方jar包的Java项目打包成jar文件的两种方法
- JAVA随机字符
- JAVA集合(2)
- 20145240 《Java程序设计》第六周学习总结
- Eclipse添加maven第三方jar包
- Spring+SpringMvc+MyBatis(Hibernate) 中关于时间格式的问题总结
- 有关Java基础的一些笔试题总结
- 一张图读懂Java多线程
- 20145206邹京儒《Java程序设计》实验报告一:Java开发环境的熟悉(Windows+IDEA)
- 5309 《Java程序设计》第6周学习总结
- LeetCode(java)4. Median of Two Sorted Arrays
- 验证签名机制——java示例
- 20145223《Java程序设计》第6周学习总结
- java正则表达式
- Eclipse中添加PyDev插件
- java连接MYSQL
- eclipse安装maven
- Eclipse上安装GIT插件EGit
- Openstack学习笔记(六)-Ubuntu下安装JDK和Eclipse
- Java NIO - Condition