《Java程序设计》第6周学习总结
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 |
posted on 2016-04-10 17:46 20145333茹翔 阅读(143) 评论(1) 编辑 收藏 举报