20145124 《Java程序设计》 第六周学习总结
本周的学习目标是:
1.理解串流与IO
2.理解InputStream/OutPutStream的继承架构
3.理解Reader/Writer继承架构
4.会使用装饰类
5.会使用多线程进行并发程序设计
在java中输入与输出被抽象化为串流
dump()的方法:
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);
}
}
}
}
若是要从HTTP服务器读取某个网页,并另存为文档,还可以使用如下方法:
package Stream;
import java.io.*;
import java.net.URL;
public class Download {
public static void main(String[] args) throws IOException {
URL url = new URL(args[0]);
InputStream src = url.openStream();
OutputStream dest = new FileOutputStream(args[1]);
IO.dump(src, dest);
}
}
将标准输出值指定文档的程序为:
package cc.openhome;
import java.io.*;
public class StandardOut {
public static void main(String[] args) throws IOException {
try (PrintStream file = new PrintStream(
new FileOutputStream(args[0]))) {
System.setOut(file);
System.out.println("HelloWorld");
}
}
}
DataInputStream,DataOutputStream用来装饰对InputStream,OutStream提供读取,写入Java基本类型的方法像是读写int,double等方法。书中有一个使用此类打包器的member的例子:
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"));
}
}
还有objectInputStream与objectOutputStream相应范例。
在建立InputStreamReader与OutputStreamWriter时可以指定编码,对字节数据转化为相应的编码字符。
BufferedReader与BufferedWriter可以将转换后的数据做缓冲处理,以增加读取效率。
线程与并行:
我们所编写的所有程序都是单线程的程序即程序开始运行时从起点到终点只有一个流程,而在本章,告诉了我们如何进行多个流程的程序设计,也就是多线程程序。如果想在main以外独自设计流程,可以撰写类操作接口java.lang.Runnable。流程的进入点是操作在run()方法中。
例如:
public class Hare implements Runnable {
private boolean[] flags = {true, false};
private int totalStep;
private int step;
public Hare(int totalStep) {
this.totalStep = totalStep;
}
@Override
public void run() {
while (step < totalStep) {
boolean isHareSleep = flags[((int) (Math.random() * 10)) % 2];
if (isHareSleep) {
System.out.println("兔子睡著了zzzz");
} else {
step += 2;
System.out.printf("兔子跑了 %d 步...%n", step);
}
}
}
}
在上面的程序中,兔子的程序运行流程会从run()开始,与乌龟不会相互影响。
使用lock分治
package Concurrency;
import java.util.concurrent.locks.*;
class Resource {
private ReentrantLock lock = new ReentrantLock();
private String name;
Resource(String name) {
this.name = name;
}
void cooperate(Resource res) {
while (true) {
try {
if (lockMeAnd(res)) {
System.out.printf("%s 整合 %s 的资源%n", this.name, res.name);
break;
}
} finally {
unLockMeAnd(res);
}
}
}
private boolean lockMeAnd(Resource res) {
return this.lock.tryLock() && res.lock.tryLock();
}
private void unLockMeAnd(Resource res) {
if (this.lock.isHeldByCurrentThread()) {
this.lock.unlock();
}
if (res.lock.isHeldByCurrentThread()) {
res.lock.unlock();
}
}
}
public class NoDeadLockDemo {
public static void main(String[] args) {
Resource res1 = new Resource("resource1");
Resource res2 = new Resource("resource2");
Thread thread1 = new Thread(() -> {
for (int i = 0; i < 10; i++) {
res1.cooperate(res2);
}
});
Thread thread2 = new Thread(() -> {
for (int i = 0; i < 10; i++) {
res2.cooperate(res1);
}
});
thread1.start();
thread2.start();
}
}
本