复习:
线程:
【用来同时执行多段代码】
【加快代码的执行速度】
前台:
不结束,jvm不能停
后台:
不结束,jvm 可以停
前台线程结束,后台线程被迫结束
1,分时
2,抢占式
1时间片,
线程生命周期 :
新建状态:
就绪状态:
运行状态: run(...);
阻塞状态
1,挂起
sleep(1000);不会放弃锁
t.join();//等待t线程执行完毕
yield();//让步,优先级相同,高.
2,锁池等待:
当前A线程执行了加锁的代码,
但是没有锁,锁被B线程拿走了。
A线程就会去锁池等待.
当B线程执行完毕以后,A线程会从锁池回到就绪状态。
两锁 --> 死锁
this
public sy void show(){}
类.class
public static sy void show(){}
3,等待池等待 锁对象.wait();
notiry();出来-->锁池-->就绪状态.
interrupt();
4死亡:run方法中代码执行完毕
线程的通信:
1,锁:wait();notify();
2,interrupt();打断
stop();
main{
//t线程被打断,给了一个标志位 true
t.interrupt();
}
获取标志位
isInterrupted(); 不会清空标志位
interrupted(); 清空标志位
IO:
【传输 数据】
【输入 输出】
【当前代码】
【字节】
【字符】
原则:
InputStream 抽象类
// 13回车\r 10 换行\n
int da = read();
//读取的数据放到字节数组中
int len = read(but);
//读取到的长度
int len = read(but,offset,len);
new String(but,0,len);
available();
skip(100L);
close();//关闭
以下是 不常用方法. 使用场景:从流中重复读入数据
2.1.7: boolean markSupported(): 返回true则表示这个流是否支持重复读入数据。
2.1.8: void mark(int):从流的当前位置开始设置标记,mark方法有个参数,通过这个整型参数,你告诉系统,希望在读出这么多个字符之前,这个mark保持有效。
2.1.9: void reset():该方法使输入流重新定位到刚才做了标记的起始位置。
mark祥解:
pos:读取的下一个位置。
markLimit: mark方法后reset方法前 最多允许读取的字节数,这个最大字节数,其实是由markLimit和buffer.size中较大的那个决定的。
当你调用mark方法时,内部会保存一个markPos标志,它的值为目前读取字节流的pos位置,倘若你调用reset方法,这时候会把pos重置为markPos的值,这样你就可以重读已经读过的字节.
eg:有一段字节流是helloworld, 当你读取完字母h调用mark方法(此时markPos指向字母e),接着你继续读取e,l,l,o 然后此时你调用reset方法(内部把pos重置为markPos),当你再读取下一个字节的时候,你会发现你读取到的是e而不是字母w,这样通过mark方法我们就是实现了重复读(re-read the same bytes)
2.2:输出流 OutputStream/writer.
2.2.1: write(int b): 向输出流写入一个字节;
2.2.2: write(byte[] b): 把字节数组中的所有字节数据写到输出流;
2.2.3: write(byte[] b, int off, int len): 把字节数组中的字节从off位置开始的数据写len个长度到输出流.
2.2.4: flush(): flush()方法强制把缓冲区内的数据写到输出流中。
注:OutputStream类本身的flush()方法不执行任何操作,
但是,一些带有缓冲区的流,在write的时候,是先把数据保存到缓冲区,并不是把数据写到流中,所以需要flash把缓冲区中的数据刷到流中。
2.2.4: close(): 关闭输出流。
package com.briup.ch17;
import java.io.OutputStream;
import java.util.Arrays;
/**
* 测试OutputStream<br>
* */
public class Test2 {
public static void main(String[] args) throws Exception {
OutputStream out = System.out;
//当前输出流 有缓冲区,
//直接写数据 会写到缓冲区中
//flush() 会将缓冲区中的内容 刷 目的地
out.write(97);
int num = 10;
out.write(num);
//局限-->
//boolean f = true;
//out.write(f);
//228 184 173 中
byte[] b1 = new byte[3];
b1[0] = (byte) 228;
b1[1] = (byte) 184;
b1[2] = (byte) 173;
out.write(b1);
String msg = "中";
// [-28, -72, -83]
//0000 0000 0000 0000 0000 0000
//1110 0100
// 128 + 64 + 32 + 4
byte[] b2 = msg.getBytes();
System.out.println(Arrays.toString(b2));
//utf-8 中
byte[] b3 = {-28,-72,-83};
out.write(b3);
//GBK 中 [-42, -48]
msg = "中";
//当前是utf-8写的[中]-->想转换为GBK编码的字节数组
byte[] b4 = msg.getBytes("GBK");
System.out.println("GBK形式的中字节数组 :"
+Arrays.toString(b4) );
//utf-8中-->转换为ISO-8859-1编码的字节数组
byte[] b5 = msg.getBytes("ISO-8859-1");
System.out.println("ISO-8859-1形式的中字节数组 :"
+Arrays.toString(b5) );
//utf-8中-->转换为US-ASCII编码的字节数组
byte[] b6 = msg.getBytes("US-ASCII");
System.out.println("US-ASCII形式的中字节数组 :"
+Arrays.toString(b6) );
//写字节数组的某一部分
byte[] b7 = {-28,-72,-83,-42,-48};
//从b7数组 3 好位置开始,输出2个长度
//判断当前系统的编码为GBK
boolean flag = true;
if(flag) {
out.write(b7,3,2);
}else {
out.write(b7,0,3);
}
out.flush();
System.out.println(out.getClass());
//输出流
//write(字节)
//write(字节数组)
//write(字节数组,offset,len);
//flush();//刷,缓冲区数据 刷到 目的地
//close();
}
}
三,IO流 各种流的操作:
前提:io操作涉及到众多的流,接下来也需要学习众多的流,只要是IO操作,用任何一种流都可以完成功能,咱学这么多流的意义在于,可以选更好的流完成。
每个流都是用到上面的基础操作,每个流也有自己的特点。咱要学的就是每个流的特点。
选用原则:
1,效率, 缓冲区字节流 > 字节流 > 缓冲区字符流 > 字符流
2,是否需要操作:基本只能是字符流(只有字符流(每次读取的是字符) 我们才能看懂,才能操作)
3.1: 字节流:InputStream/OutputStream:
一般是一次读取一个字节
Unicode:16位表示一个字符->两个字节表示一个字符。
3个字节 表示一个 中文字符
utf-8:属于Unicode一个子类: 是根据字符对应的数字大小来确定.
注:在控制台输入的时候 需要注意控制台编码,右键->run as->common->Encoding
String msg = new String(byte[]);
String msg = new String(byte[],start,len);
3.2: 字节流:ByteArrayInputStream/ByteArrayOutputStream:从字节数组中读取数据/把数据写到字节数组中。
专门用来读取字节数组。
ByteArrayInputStream
字节数组输入流:
1,具有缓冲区
2,在创建该流的时候,就会把字节数组中所有的内容读取到缓冲区中。
3,加快读取的效率
4,read();读取到流末尾 会返回 -1
ByteArrayOutputStream
有缓冲区的输出流
1,write(数据);写到了缓冲区中
2,flush();缓冲区中数据刷 到 目的地
缓冲区:加快执行速度,减少io操作
package com.briup.ch17;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.Arrays;
/**
* 字节数组输入流<Br
* ByteArrayInputStream<br>
* 从字节数组中读取数据<Br>
* */
public class Test4 {
//测试ByteArrayOutputStream
public static void main(String[] args) throws Exception {
//具有缓冲区的字节数组输出流
ByteArrayOutputStream baos
= new ByteArrayOutputStream();
baos.write(97);
baos.write(13);
baos.flush();
//获取字节数组输出流缓冲区中所有的数据
byte[] byteArray = baos.toByteArray();
String string = baos.toString();
System.out.println(Arrays.toString(byteArray));
System.out.println(string);
}
public static void mainin(String[] args) throws Exception {
byte[] buf = {97,98,99,100,101};
//创建:已经把字节数组中的数据加载到bais流的缓冲区中
ByteArrayInputStream bais =
new ByteArrayInputStream(buf);
//读取字节数组中内容
//while(true) {
//读取到流的末尾 返回 -1
int da = bais.read();
System.out.println(da);
//}
}
}
3.3: 字节流:FileInputStream/FileOutputStream:从文件中读取数据/把数据输出到文件中。
3.3.1: File 类:
构造器1:new File("src/aa");创建src/aa新File 实例。
构造器2:new File(file2,"a.aaa");在file2目录下a.aaa新File 实例。file2不是目录会报错
构造器3:new File("src/ab","b");创建 src/ab目录下的 b新File 实例。src/ab 目录不存在 会报错
静态属性: pathSeparator 与系统相关的路径分隔符字符.
window : ;
unix : :
静态属性: separator 与系统相关的路径分隔符字符.
winwod : \\
unix : /
package com.briup.ch17;
import java.io.File;
/**
*File类的构造器<Br>
* */
public class Test6 {
public static void main(String[] args) throws Exception {
//路径名
/*
* 1.png相对路径,
* 当前路径是项目下
* */
File f1 = new File("1.png");
//f1.delete();
File f2 = new File("src/com/briup/ch17/Test1.java");
//选择.java文件 右键
///jd1907_corejava/src/com/briup/ch17/Test1.java
//选择.java中的类 右键
//Class.forName(com.briup.ch17.Test1)
//绝对路径
// window D:// C://
File f3 = new File("D://a.txt");
System.out.println(f3.length());
//构造器二:
//parent路径一定要指向文件夹,
//child子文件名字,文件名 文件夹名
File f4 = new File("D:\\soft\\360zip", "config");
System.out.println(f4.length());
//parent一定要是文件夹,不然没有意义
File parent = new File("D://soft/360zip");
File f5 = new File(parent, "7z.dll");
}
}