Day18
----------------------------------------------------------------------------------
今天内容:
(1)IO流
(2)线程
1.IO流
1.1 PrintStream类(重点 与BufferedReader类搭配使用)
(1)基本概念
java.io.PrintStream类主要用于方便地打印各种数据内容。
(2)常用的方法
PrintStream(OutputStream out) - 根据参数指定的引用来构造对象。
- 其中OutputStream类是个抽象类,实参需要传递子类的对象形成多态
void print(String s) - 用于打印参数指定的字符串。
void println(String x) - 用于打印字符串并换行。
void close()
1.2 ObjectOutputStream类(重点)
(1)基本概念
java.io.ObjectOutputStream类主要用于将Java对象整体写入输出流中。
只能将支持 java.io.Serializable 接口的对象写入流中。
类通过实现 java.io.Serializable 接口以启用其序列化功能。
所谓序列化就是指将一个对象的特征等相关信息有效组织成字节序列的转化过程。
(2)常用的方法
ObjectOutputStream(OutputStream out) - 根据参数指定的引用来构造对象。
- 其中OutputStream类是个抽象类,实参需要传递子类对象形成多态。
void writeObject(Object obj)
- 用于将参数指定的对象整体写入输出流。
void close()
1.3 ObjectInputStream类(重点)
(1)基本概念
java.io.ObjectInputStream类主要用于从输入流中读取整个对象。
(2)常用的方法
ObjectInputStream(InputStream in) - 根据参数指定的引用来构造对象。
- 其中InputStream类是个抽象类,实参需要传递子类对象形成多态。
Object readObject() - 用于从输入流中读取对象并返回。
- 无法通过返回值来判断是否读到末尾。
void close()
经验的分享:
在以后的开发中当需要将多个对象写入文件时,则建议先将多个对象放入一个集合中,然后将集合整体看做一个对象写入文件,此时读取文件中内容时只需要调用一次readObject()即可,从而避免通过返回值来判断是否读到末尾的操作。
2.线程
2.1 基本概念
程序 - 主要指存放在硬盘/磁盘上的可执行文件。
进程 - 主要指在内存中运行的程序。
目前主流的操作系统都支持多进程,是为了同时执行多个任务,但进程是重量级的,新建进程对系统资源的消耗比较大,因此进程启动的数量是有限的。
线程是进程内部的程序流,也就是操作系统支持多进程,而每个进程内部又支持多线程,并且线程是轻量级的,新建线程对系统资源的消耗比较小,因此主流的开发都采用多线程技术。
目前主流的多线程技术采用时间片轮转法来达到多线程并发执行的效果,所谓并发就是宏观并行,微观串行的机制。
2.2 线程的创建(重中之重)
(1)线程创建的方式
java.lang.Thread类用于描述线程,Java虚拟机允许应用程序并发地运行多个执行线程,而线程创建和启动方式如下:
a.自定义类继承Thread类并重写run()方法,然后创建该类的对象后调用start()方法;
b.自定义类实现Runnable接口并重写run()方法,然后创建该类的对象作为实参去创建
Thread类的对象,最后使用Thread类对象调用start()方法。
(2)相关的方法
Thread() - 用于使用无参的方式构造对象。
Thread(String name) - 根据参数指定的名称来构造对象。
Thread(Runnable target) - 根据参数指定的接口引用来构造对象。
Thread(Runnable target, String name) - 根据参数指定引用和名称共同构造对象。
void run() - 若使用Runnable引用来构造线程对象,则调用该方法的结果就是
调用Runnable引用指向对象的run方法。
- 若没有使用Runnable引用构造线程对象,则调用该方法的结果是啥也不干。
void start() - 用于启动线程,Java虚拟机会自动调用该线程的run()方法。
(3)实现原理
a.执行main()方法的线程叫做主线程,执行run()方法的线程叫做子/新线程。
b.main()方法是程序的入口,主线程先执行main()方法的代码,对于start()方法调用
成功之前的代码来说,由主线程执行一次,当start()方法调用成功后线程的个数由1
个变成了2个,主线程继续向下执行,新启动的线程去执行run()方法的代码,两个线程
同时执行,互不影响。
c.当main()方法结束后主线程终止,当run()方法结束后子线程终止,两个线程的执行
先后次序没有明确的规定,由系统的调度算法决定。
注意:
继承的方式相对来说代码比较简单,但Java语言只支持单继承,若当前类继承了Thread类则无法继承其它类,因此以后的开发中推荐实现接口的方式,因为此方式不仅不影响继承而且支持多实现,缺点是代码比较复杂。
2.3 线程的主要状态(了解)
新建状态 - 当使用new关键字创建线程对象后进入的状态。
- 此时线程还没有开始执行。
就绪状态 - 当线程对象调用start()方法后进入的状态。
- 此时线程依然没有开始执行。
运行状态 - 当线程线程调度器调度已经就绪状态的线程后进入的状态。
- 此时线程开始执行。
- 当线程的时间片执行完毕后但任务没有完成则回到就绪状态。
消亡状态 - 当线程的时间片执行完毕后任务已经完成时进入的状态。
- 此时线程已经终止。
阻塞状态 - 当线程执行的过程中发生阻塞事件时进入的状态,如:sleep()方法
- 当阻塞状态解除后回到就绪状态。
2.4 线程的编号和名称(查手册会用即可)
long getId() - 用于返回线程的标识符/编号。
String getName() - 用于返回线程的名称。
void setName(String name) - 用于更改线程的名称。
static Thread currentThread() - 用于返回当前正在执行线程对象的引用。
作业:
1.重点掌握线程创建的两种方式。
2.要求在学生信息管理系统中增加两个功能:
a.要求启动该项目时,先读取文件中的所有学生信息。
b.要求退出该项目时,将所有的学生信息写入到文件中。