Java基础补习Day6

一、文件IO补充

1、Reader/Writer 字符流的基类

1.1 Reader

继承关系:
    Object父类
    Closeable Readable 父接口。
构造器:
    构造器都是protected,专门给子类设计。(抽象类)
方法:
    read() 读取字符。
    close() 关闭流。

1.2 Writer

继承关系:
    Object父类
    closeable, Flushable, Appendable 父接口。
构造器:
方法:
    append()方法
    close()关闭流
    flush()刷新
    write()写字符

1.3 实现子类:

OutputStreamWriter
    继承关系:继承Writer
    构造器:
        OutputStreamWriter(OutputStream out) :要基于OutputStream对象来创建。
InputStreamReader
    继承关系:继承Reader
    构造器:
        InputStreamReader(InputStream in) :要基于InputStream对象来创建。

注意:

java中流的分类,还可以按照是否基于别的流创建对象:
不基于别的流创建对象:节点流
基于别的流创建对象:  处理流 

2、BufferedReader

继承关系:继承Reader
构造器:BufferedReader (reader) 基于别的Reader对象,来创建。

注意:这里我们可以看到很多的流在实现功能增强时,采用了一种俄罗斯套娃形式,逐步实现了对内层流功能的增加。这种代码的编写格式就是装饰模式。

3、BufferedWriter

BufferedWriter和BufferReader相类似


BufferReader已实现了字节到字符转换的麻烦,下面两个也已实现了字节到基本数据类型数值的转换
DataInputStream
    继承关系:FilterInputStream
    接口:closeable,DataInput
DataOutpuStream
    继承关系:FilterOutputStream
    接口:Closeable, Flushable,  DataOutput

4、 对象序列化:

4.1 对象输入输出流:

ObjectInputStream/ObjectOutputStream

WriteObject():将对象写入输出流中
ReadObject():从 ObjectInputStream 读取对象

将对象转化为流:序列化。
将流转化为对象:反序列化。

4.2 属性的隐藏:

1.transient 临时会属性,让对象在序列化时,此属性不被序列化。

如果被transient修饰的属性,我们想要序列化他怎么办?

2.自定义序列化方法:
这两个方法写法固定,而且并没有用过接口来规范,所以我们通常从api中拷贝出来:
private void writeObject(java.io.ObjectOutputStream out)
        throws IOException ;
private void readObject(java.io.ObjectInputStream in)
        throws IOException, ClassNotFoundException;
他们writeObject负责对象的序列化:序列化属性。
         readObject负责对象的反序列化:取出我们保存的属性。

3.自定义序列化接口:
如果我们忘记了上面方法的写法,又必须实现自定义序列化:
Externalizable 自定义序列化接口:
        writeExternal() ;
        readExternal() ;

如果序列化和反序列化发生在了两个程序中,这个时候,java是要求我们必须显示地为序列化类型设置一个UID:
static final long serialVersionUID = 42L;

二、进程与线程:

1.定义:

进程:在每个系统中,每个系统有自己独自的定义。通常来讲进程就代表一个程序。

线程:线程是代码的执行流程。我们程序启动,会创建一个进程,在这个进程中通常都会带有一条线程,这条线程会找到main方法,并从main开始逐条执行我们的语句。

注意:
- 在java中,我们没有一个明确的api专门负责操作进程。这个java是通过JNI技术通过native方法调用本地api来执行的。
- 一个进程中可以拥有多条线程。

2.关键类

Thread 和 Runnable

Thread类是Java对线程的描述。
Runnable接口是Java对线程任务的规范,其中有run()方法,线程所有执行的任务都要在run()方法里

3.启动线程

方式1:创建Thread对象,创建Runnable的子类型实现run方法,Thread启动线程start(),并回调run方法

方式2:实现Thread类型的的子类型,并扩展run方法,再由Thread启动线程start()

4.线程的调度

4.1 停止

  • 当线程的任务执行完毕,自动销毁
  • stop()和destory()方法终止线程,但不推荐
  • 抛出异常
正常来说我们要停止线程,我们采用方法1,让run方法中的任务执行完毕,线程自动销毁。

4.2 让出CPU :yield()

让出cpu的执行权,然后重新去获取。

4.3 线程的优先级

相关方法
getPriority():获取该线程的优先级
setPriority():设置该线程的优先级

4.4 sleep():

使线程进入“睡眠”状态。在规定的时间内,这个线程是不会运行的。同时让出CPU

4.5 join():

线程都是同时执行的,如果有两条线程,要实现一条线程A先执行,另一条线程B再执行,可以在B线程中调用A.join(),从而实现B等待A执行完毕,再执行。

4.6 线程所带来的问题

当多条线程对同一个数据进行操作时,可能发生数据同步问题。所以我们需要多个线程处理一个数据时,同时只允许一条线程对数据进行操作,执行完毕后,交由后面等候的一条线程执行。

如何解决上述问题,让线程同步呢?

java中提供了一个由对象实现的互斥锁,我们可以通过锁将数据进行保护,保证同一时刻,只有一条线程能操作。

锁的使用:
1.java中所有对象都持有一把同步锁。不同对象的同步锁不会互相作用。
2.多条线程要实现同步操作,必须基于同一个对象的锁实现,锁代码块,才能起作用。

锁的方式:
synchronized(锁对象){
    锁住的代码。
}
public synchronized void func(){
    锁住的代码。//锁方法是锁的this对象。
}

4.7.wait()和notify()

wait(): 锁语句块中,让线程停止。
notify() /notifyAll():在同一个锁的语句块中,让wait停止的线程重新启动。

notify()是唤醒在这个对象上等待的一条线程(随机),notifyAll()是唤醒在这个对象上等待的所有的线程。

作用:

让一条线程在一个对象A上等待(停止),需要唤醒时,由另一条线程调用对象A的唤醒方法,来唤醒在对象上等待的那条线程。

注意:

这两个方法都是Object的方法,虽然是作用于Thread,但是由于实现是基于对象来实现的,所以他们是Object的方法。

你可能感兴趣的:(Java基础补习)