《Java程序设计》第6周学习总结
2016-04-10 17:46
417 查看
20145333 《Java程序设计》第6周学习总结
教材学习内容总结
输入和输出串流设计概念
要想活用输入/输出API,一定先要了解Java中如何以串流抽象化输入/输出概念,以及InputStream,OutputStream继承架构。如此一来,无论标准输入/输出,文档输入/输出,网络输入/输出,数据库输入/输出,都可以用一致的操作进行处理。
从应用程序来看,如果要将数据从来源取出,可以使用输入串流:如果要将数据写入目的地,可以使用输出串流,在Java中,输入串流代表对象为java.io.InputStream实例,输出串流代表对象为java.io.OutputStream实例,无论数据源或目的地为何,只要设法取得InputStream或OutputStream的实例,接下来操作输入/输出的方式是一致的,无须理会来源或目的地的真正形态。
package Stream; import java.io.*; public class IO { public static void dump(InputStream src, OutputStream dest) throws IOException { try (InputStream input = src; OutputStream output = dest) { byte[] data = new byte[1024]; int length; while ((length = input.read(data)) != -1) { output.write(data, 0, length); } } } }
串流继承架构
System.in与System.out分别是InputStream和OutputStream的实例。
可以使用System的setIn()方法指定InputStream实例,重新指定标准输入来源。
ByteArrayInputStream是InputStream的子类,可以指定byte数组创建实例,一旦创建就将byte数组当作数据源进行读取,同理,ByteArrayOutputStream将byte数组当作目的地写出数据。
串流处理装饰器
串流装饰器本身并没有改变InputStream和OutputStream的行为,只是在得到数据之后,再做一些加工处理。
·BufferedInputStream与BufferedOutputStream主要在内部提供缓冲区功能。
package Stream; import java.io.*; public class BUfferedIO { public static void dump(InputStream src, OutputStream dest) throws IOException { try(InputStream input = new BufferedInputStream(src); OutputStream output = new BufferedOutputStream(dest)) { byte[] data = new byte[1024]; int length; while ((length = input.read(data)) != -1) { output.write(data, 0, length); } } } }
·DataInputStream与DataOutputStream主要提供读取、写入java基本数据类型的方法,会自动在指定的类型与字节之间转换。
package Stream; 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")); } }
字符处理装饰器
如果串流处理的字节数据,实际上代表某些字符的编码数据,而你想要将这些字节数据转换为对应的编码字符,可以使用InputStreamReader、OutputStreamWriter对串流数据打包,在建立InputStreamReader与OutputStreamWriter时,可以指定编码,如果没有指定编码,则以JVM启动时所获取的默认编码来做字符转换。PrintStream与PrintWriter使用上极为相似,不过除了可以对OutputStream打包之外,PrintWriter还可以对Writer进行打包,提供print()、println()、format()等方法。
线程与并行API
线程
在java中,如果想在main()以外独立设计流程,可以撰写类操作java.lang.Runnable接口,流程的进入点是操作在run()方法中。
在java中,从main()开始的流程会由主线程执行,可以创建Thread实例来执行Runnable实例定义的run()方法。
等待与通知
wait()、notify()、notifyAll()是object定义的方法,可以通过这3个方法控制线程释放对象的锁定,或者通知线程参与锁定竞争。若调用锁定对象的wait()方法,线程会释放对象锁定,并进入对象等待集合从而处于阻断状态,其他线程可以竞争对象锁定,取得锁定的线程可以执行synchronized范围的程序代码。放在等待集合的线程不会参与CPU排班,wait()可以指定等待时间,时间到之后线程会再次加入排班。如果指定时间0或不指定,则线程会持续等待,直到被中断(调用interrupt())或是告知(notify())可以参与排班。
并行API
Lock 接口主要操作类之一为 ReentrantLock,可以达到synchronized 的作用,也提供额外的功能,例:
package cc.openhome;
import java.util.Arrays; import java.util.concurrent.locks.*; public class ArrayList<E> { private Lock lock = new ReentrantLock(); private Object[] elems; private int next; public ArrayList(int capacity) { elems = new Object[capacity]; } public ArrayList() { this(16); } public void add(E elem) { lock.lock(); try { if (next == elems.length) { elems = Arrays.copyOf(elems, elems.length * 2); } elems[next++] = elem; } finally { lock.unlock(); } } public E get(int index) { lock.lock(); try { return (E) elems[index]; } finally { lock.unlock(); } } public int size() { lock.lock(); try { return next; } finally { lock.unlock(); } } }
使用ReadWriteLock
ReadWriteLock接口定义了读取锁定与写入锁定行为,可以使用readLock()、writeLock()方法返回Lock操作对象。ReentrantReadWriteLock是ReadWriteLock接口的主要操作类,readLock()方法会返回ReentrantReadWriteLock.ReadLock实例,writeLock()犯法会返回ReentrantReadWriteLock.WriteLock实例。
使用StampedLock
StampedLock类可支持了乐观读取操作。也就是若读取线程很多,写入线程很少的情况下,你可以乐观地认为,写入与读取同时发生的机会很少,因此不悲观的使用哇暖的读取锁定,程序可以查看数据读取之后,是否遭到写入线程的变更,再采取后续的措施。
使用Condition
Condition接口用来搭配Lock,最基本用法就是达到Object的wait()、notify()、notifyAll()方法的作用。Condition的await()、signal()、signalAll()方法,可视为Object的wait()、notify()、notifyAll()方法的对应。
教材学习中的问题和解决过程
撰写单线程序、多线程程序的方式差别:操作Runnable接口的好处就是较有弹性,类还有机会继承其他类;若继承了Thread类,那该类就是一种Thread,通常是为了直接利用Thread中定义的一些方法,才会继承Thread来操作。InputStream、Reader与Writer区别:
Writer针对于字符数据写入,Reader针对于字符数据的读取,InputStream针对于串流输入
本周代码托管截图
地址http://git.oschina.net/20145333/java-besti-is-2015-2016-2-20145333/tree/master
其他(感悟、思考等,可选)
每周的学习都有新的体会,随着学习的不断深入,学习内容中出现了越来越多新的概念,也对以前的内容有了更深的理解。学习进度条
代码行数(新增/累积) | 博客量(新增/累积) | 学习时间(新增/累积) | 重要成长 | |
---|---|---|---|---|
目标 | 3500行 | 15篇 | 400小时 | |
第一周 | 100/100 | 2/2 | 20/20 | |
第二周 | 150/250 | 1/3 | 18/38 | |
第三周 | 100/350 | 1/4 | 22/60 | |
第四周 | 300/650 | 1/5 | 30/90 | |
第五周 | 100/750 | 1/6 | 20/110 | |
第六周 | 350/1100 | 1/7 | 25/135 |
相关文章推荐
- 20145227《Java程序设计》第1次实验报告
- java递归获取某个父节点下面的所有子节点
- Struts2类型转换
- SpringMVC教程(一)框架搭建
- 解决springMVC POST 中文乱码
- 严重: Dispatcher initialization failed java.lang.RuntimeException: java.lang.reflect.InvocationTargetE
- [疯狂Java]SQL:子查询
- Spring各jar包的作用
- 图文详解 IntelliJ IDEA 15 创建普通 Java Web 项目
- 日期
- java递归算法总结
- 在配置spring配置文件时报错,解决办法
- java 实现二分归并排序
- java中创建对象的方法(转)
- JavaWEB+Ajax实现文件上传
- LeetCode 206 -Reverse Linked List ( JAVA )
- 深入理解java虚拟机--线程安全与优化
- Spring中@Transactional用法深度分析之一
- RxJava 常见误区(一):过度使用 Subject
- JAVA 内部类