Java 异常处理机制
Throwable类
Java中异常的顶级父类
在其下有两个子类:
1:Error:jvm级别的错误。
例如:栈内存溢出
2:Exception:程序级别的错误
可以通过捕获机制来解决
try语句
try{
可能出现异常的代码片段
}
try语句用来包围可能出现异常的代码片段。
try是发现问题的语句
catch语句
catch(Exception_Type e){
解决问题的代码段
}
catch语句是用来捕获try语句出现的异常,并针对该异常解决的。catch语句块可以出现多次。
throw语句
throw e;
throw语句用来主动抛出一个异常的实例。
通常情况下会主动抛出异常:
1:我们定义的方法在运行过程中出现了错误,而这个错误如何解决应该由调用者决定时,我们会将异常抛出。
2:当我们遇到一个不符合业务逻辑的操作时我们可以把它当做一个异常去处理。而主动抛出。
throws声明
我们定义的方法中可能会出现错误,无论是否为我们主动抛出的,但是要是方法中出现的异常不在方法中处理的,我们通常在声明方法时同时声明可能抛出的异常。通知调用者必须捕获。(丑话说前面)
finally块
finally{
代码片段
}
finally出现在try语句的最后
finally块中的语句是必然执行的,无论try中是否出现异常。
重写方法时的异常处理
若父类方法中通过throws声明了某些异常的抛出,那么:
1:子类重写时可以不声明throws;
2:子类在重写父类方法时可以抛出父类抛出的异常的子类异常(子类抛出的异常不能比父类的还大)
举例:
父类方法throws RuntimeException
子类可以:
ThrowsNullPointerException
3:子类重写时可以只抛出父类抛出的部分异常
但是不能:
1:子类重写时不能抛出父类方法中没有抛出的额外异常
2:子类重写时不能抛出父类方法中抛出的异常的父类异常
Java对操作系统中文件系统的支持
File类
用于描述操作系统中的一个文件或目录
通过File我们可以得知文件的名字,大小,修改时间等信息。但是不能读取文件内容
RandomAccessFile :用于读写文件内容的类
Java中的文件模型
数据在硬盘中保存的形式是byte by byte
读写文件实际上就是读写字节
创建RandomAccessFile
RandomAccessFile (File file ,String mode)
mode 支持两个:
“rw”:读写
“r”:只读
Java中的IO 输入流与输出流
InputStream: 输入流:用于从外界读取数据到程序中
OutputStream: 输出流:将程序中的数据发送到外界
Java中的流分为
低级流:节点流 数据的来源与去向明确
高级流:处理流,过滤流 不能独立存在,通常基于一个流进行工
作,即使用高级流可以简化我们的读写操作
根据流读写数据的单位通常划分为: 字节流 和 字符流
字节流:以字节为单位读写数据
字符流:以字符为单位读写数据
java.io中输入流与输出流的父类
java.io.InputStream 这是一个抽象类,不能实例化,是所有输入
流的父类
java.io.OutputStream 这也是一个抽象类,不能实例化,是所有输
出流的父类
其中定义了写出数据的相关方法。
FIS与FOS
文件字节输入输出流
FileInputStream:
用于读取文件的字节流
FileOutStream:
用于向文件写数据的字节流
具有缓冲功能的输入输出流:(高级流) BIS 与 BOS
BufferedInputStream 缓冲字节输入流
BufferedOutputStream 缓冲字节输出流
用于读写基本类型数据的DataIputStream
DataOutputStream
字符流:读写以字符为单位
字符流的父类 java.io.Reader
java.io.Writer
子类实现: InputStreamReader
OutputStreamWriter
读写数据都是基于字节的,所以字符流都是高级流
缓冲字符输入输出流
特点:以行为单位读写字符
BufferedReader:缓冲字符输入流
BufferedWriter:缓冲字符输出流
用于读取文本文件的字符流
FileReader:文件字符输入流
FileWriter:文件字符输出流
Day04
PrintWriter: 带自动刷新的缓冲字符输出流
常用的构造方法:
PrintWriter(Filefile)
创建一个给定文件写数据的 PrintWriter 该种创建方式是创
建了一个不自动刷新的流
PrintWriter(OutputStream out)
创建一个不具备自动刷新的基于给定的字节输出流进行写操作
的PrintWriter
PrintWriter(OutputStreamout,
Boolean antoFlush)
创建一个具备自动刷新的基于给定字节输出流进行写操作的
PrintWriter
但具有自动刷新后,每当我们通过该流写一行字符串后都会自动
flush()清空缓冲区并作一次写操作
PrintWriter(Writerw)
PrintWriter(Writerw,boolean autoFlush)
PrintWriter(StringFilePath) 根据给定的文件路径,创建基
于该文件写操作的PrintWriter
DataInputStream
DataOutputStream
写一个基本类型数据的基本过程
1:将一个基本的类型数据转化为相应的字节
2:将这些字节有序的写入文件保存
将程序中的数据转化为对应的字节的过程称之为“序列化”
这里的第1部分实际上就是将基本类型数据进行了序列化,我们
称之为“基本数据类型序列化”
第2步中我们将数据写入硬盘中做长久保存的过程称之为“数据
持久化”
将字节转换为数据的过程叫做“反序列化”
可以对 对象 进行序列化与反序列化的流
ObjectInputStream:读取字节并转换为对象的输入流(反序列化)
ObjectOutputStream:将对象转换为字节后并写出来的流
Java语言的一个优势就是处理多线程比较简单
一般操作系统都支持同时执行多个程序,那么每个同时运行的程序对操作系统而言称为一个进程,而对于一个程序而言,内部也可能同时运行多个任务,那么每个同时运行的任务称为一个线程。
无论是进程还是线程,任务都是并发运行的,而不是纯粹的同时运行。同时只是宏观上看。
所谓的并发,就是宏观上看所有任务都在同时运行,但微观上讲每一个程序都是走走停停的。
创建线程的步骤:
1:定义一个类,并继承Thread类
Thread类就是线程类,其中定义这操作线程的相关方法
2:重写run方法,该方法中应该定义的内容就是要并发运行的代码
片段
3:实例化线程并启动
并发的执行过程:
当一个线程调用了start()方法时,该线程纳入线程调度机制。得以并发运行。
线程调度机制会分配时间片段,获得时间片段的线程被CPU执行,但时间片段的时间耗尽,那么该线程等待,线程调度机制会再次分配时间片段给一个线程。
这里要注意:
时间片段的时间不是完全均匀的,而且所有并发运行的任务获取时间片段的几率也不完全相同,但是线程调度机制会尽可能的均匀分配。
一个线程获取时间片段的长短,以及被分配的次数是通过程序不可控的。
葛优同时拍赵氏孤儿,非诚勿扰2,让子弹飞 是很典型的现实版并发操作
联想: CPU: 葛优
线程调度机制: 葛优经纪人
时间片段: 档期
线程:剧组
前面创建线程的方式有一个弊端,就是定义线程的时候就决定了该线程要运行的任务
我们应该尽可能避免线程与其要执行的任务关联性太强。
应该换一种思路:
任务就是任务,线程就是线程,线程只关心可以并发运行即可,给什么任务就并发运行什么任务。
线程常用的方法:
static void sleep(long time)
让当前线程进入睡眠阻塞time毫秒,但时间消耗完毕后,线程重新回到runnable状态
void interrupt() 中断线程
final void setPriority(int p) 设置优先级,参数的取值范围:
1-10,对应三个常量:MAX_PRIORITY :10
NORM_PRIORITY :5
MIN_PRIORITY :1
Day05
守护线程(后台线程)
当一个进程中的所有前台线程运行完毕后,所有的后台线程均要强制结束。
进程的结束:
当一个进程的所有进程结束后,该进程结束。
线程安全问题:
由于多线程访问统一数据时可能出现线程安全问题,我们需要在访问数据的地方保证同步操作,就是要有先后顺序,不能同时访问。
Synchronized关键字
当synchronized关键字修饰方法时,该方法变成同步方法,多个线程不能同时执行该方法。
若修饰方法,那么所对象是当前对象,换句话说就是给this上了个锁。
当一个类的两个方法都被上了锁,那么这两个方法是互斥的,也就是说只有一个被访问。
当一个类中声明的多个方法均被synchronuzed修饰,
那么这些方法是互斥关系,同一时间不可能被同时调用。
若所有的操作军都对方法进行同步,显然效率低下,在方法中,有时只有部分代码需要同步,这时候我们只需同步这部分即可,这样可以提高同步效率。
语法:
synchronized(同步监视器){
}
同步监视器就是要上锁的对象。通常使用的同步监视器(上所对象)是this。
线程安全与不安全的类
线程安全的 线程不安全的
StringBuffer StringBuilder
Vector ArrayList
Hashtable HashMap
很多应用中都需要使用多线程,二有些情况当一个线程要完成的工作需要另一个线程的工作情况时,我们则需要两个线程协调工作
以下方法是在Object中定义的:
wait():在当前线程上等待
notify():通知一个在当前对象上等待的线程运行。
notifyAll():通知所有在当前对象上等待的线程回到runna状态
Day06
java Socket
java网络开发
Socket套接字
网络应用的模式:
C/S:客户端对服务器端
客户端是根据需求制定的,有特定的传输协议。
可以为用户提供更准确的需求,更好的用户体验。
但是对于更新和维护来讲,需要影响用户,所以维护和更新是弊端。
B/S:浏览器对服务器端
通信协议一致,客户端一致的特殊C/S结构应用。
java.net.Socket
java.net.ServerSocket
Socket运行在客户端
ServerSocket运行在服务端
链接方式永远是Socket链接ServerSocket
/sbin/ifconfig
双缓冲队列
BlockingDeque接口
其有几个实现类:
ArrayBlockingQueue:规定大小的缓冲队列,其构造放啊需要带一个
int参数。规定该队列长度。该队列存取元素遵循FIFO
LinkedBlockingQueue:不定长的缓冲队列。最大值为
Intefer.MAX_VALUE.存取元素遵循FIFO.
PriorityBlickingQueue:不定长缓冲队列,存取元素时不遵循FIFO,
由自然排序决定。
SynchronizedQueue:特殊的缓冲队列,存取元素必须交替进行。
线程池
ExecutorService
创建线程池
Executors.newCachedThreadPool()
可以根据需要创建线程,并在这些线程空闲时重用它们。
Executor.newFixedThreadPool(int size)
创建一个固定大小的线程池,并在线程空闲时重用它们。
Executors.newScheduleThreadPool(int size)
创建一个具有延迟执行任务的线程池。
Executors.newSingleThreadExecutor()
使用单线程方式工作