标签:字符 rand doc 体验 override ring size 输入 error
异 常
什么是异常:异常是指在程序的运行过程中所发生的不正常的事件,它会中断运行的程序。
异常处理通过五个关键字来实现:try、catch、finally、throw和throws
try:执行可能产生的异常代码(try包裹整个执行的代码从头到尾)
catch:捕获异常,根据执行条件写入相关异常类型。
finally:无论是否发生异常,代码都能执行。
throw:声明方法可能要 抛出的各种异常,只能用于抛出一种异常。
throws:手动抛出异常,让调用者处理异常
try-catch块
在catch块中处理异常
1.加入用户自定义处理信息
System.err.println("出现错误:年龄不能是负数")
2.调用方法输出异常信息
e.printStackTrace();
3.异常处理方法
1.void printStackTrace() 输出异常的堆栈信息
2.String getMessage() 返回异常信息描述字符串,是printStackTrace()输出信息的一部分。
常见的异常类型
Exception 异常层次结构的父类
ArithmeticException 算术错误情形,如以零作除数
ArraylndexOutOfBoundsException 数组下标越界
NullPointerException 尝试访问 null 对象成员
ClassNotFoundException 不能加载所需的类
IllegalArgumentException 方法接收到非法参数
NumberFormatException 数字格式转换异常
ClassCastException 对象强制类型转换出错
多重catch块
1.排列catch 语句的顺序:先子类后父类
2.发生异常时按顺序逐个匹配
3.只执行第一个与异常类型匹配的catch语句
异常的分类
Error:程序本身的异常,重启程序或没有解决办法。(现实中硬件出问题了,只能更换硬件)
Exception:分为检查性异常和非检查性异常。
检查性异常:必须在编写代码时,使用try catch捕获。
非检查性异:在Java中所有RuntimeException的派生类都是非检查型异常,与检查型异常对比,非检查型异常可以不在函数声明中添加throws语句,调用函数上也不需要强制处理。如果有异常产生,则异常将由JVM虚拟机进行处理。
log4j记录日志
日志(log)
主要用来记录系统运行中一些重要操作信息。
便于监视系统运行情况,帮助用户提前发现和避开可能出现的问题,或者出现问题后根据日志找到原因。
log4j
控制日志的输出级别。
控制日志信息输送的目的地是控制台、文件等。
控制每一条日志的输出格式。
Java集合框架
Java集合框架提供了一套性能优良、使用方便的接口和类,它们位于java.util包中
java.util包中常用的类和接口
1.常用接口
(1)Collection
Collection 层次结构 中的根接口。
(2)Iterator
对 collection 进行迭代的迭代器。
(3)List
有序的 collection(也称为序列)。
(4)Map
将键映射到值的对象。
(5)Map.Entry
映射项(键-值对)。
(6)Set
一个不包含重复元素的 collection。
2.常用类
ArrayList
List 接口的大小可变数组的实现。
Arrays
此类包含用来操作数组(比如排序和搜索)的各种方法
Collections
此类完全由在 collection 上进行操作或返回 collection 的静态方法组成。
Date
类 Date 表示特定的瞬间,精确到毫秒。
HashMap
基于哈希表的 Map 接口的实现。
HashSet
此类实现 Set 接口,由哈希表(实际上是一个 HashMap 实例)支持。
Random
此类的实例用于生成伪随机数流。
Timer
一种工具,线程用其安排以后在后台线程中执行的任务。
接口
collection接口存储一组不唯一,无序的对象。
List 接口存储一组不唯一,有序(插入顺序)的对象。
Set 接口存储一组唯一,无序的对象。
Map接口存储一组键值对象,提供key到value的映射。
List:
ArrayList可变数组,在内存中分配连续的空间。访问效率比较高。
LinkedList采用链表存储方式。插入、删除(修改)元素时效率比较高
常用方法
LinkedList:频繁修改时,可使用LinkedList来提高效率。提供头尾元素进行添加和删除操作的方法
使用方法:
迭代器Iterator
如果遇到遍历容器时,判断删除元素的情况,使用迭代器遍历。
/*
*迭代器遍历Set
*/
public class Test {
public static void main(String[] args) {
Set<String> set = new HashSet<String>();
for (int i = 0; i < 5; i++) {
set.add("a" + i);
}
System.out.println(set);
for (Iterator<String> iter = set.iterator(); iter.hasNext();) {
String temp = iter.next();
System.out.print(temp + "\t");
}
System.out.println();
System.out.println(set);
}
}
迭代器遍历Map
//1 public class Test { public static void main(String[] args) { Map<String, String> map = new HashMap<String, String>(); map.put("A", "王五"); map.put("B", "小赛文"); Set<Entry<String, String>> ss = map.entrySet(); for (Iterator<Entry<String, String>> iterator = ss.iterator(); iterator.hasNext();) { Entry<String, String> e = iterator.next(); System.out.println(e.getKey() + "--" + e.getValue()); } } } //2 public class Test { public static void main(String[] args) { Map<String, String> map = new HashMap<String, String>(); map.put("A", "王五"); map.put("B", "小赛"); Set<String> ss = map.keySet(); for (Iterator<String> iterator = ss.iterator(); iterator.hasNext();) { String key = iterator.next(); System.out.println(key + "--" + map.get(key)); } } }
多线程
在一般情况下,创建一个线程是不能提高程序的执行效率的,所以要创建多个线程。但是多个线程同时运行的时候可能调用线程函数,在多个线程同时对同一个内存地址进行写入,由于CPU时间调度上的问题,写入数据会被多次的覆盖,所以就要使线程同步。
在多线程编程里面,一些敏感数据不允许被多个线程同时访问,此时就使用同步访问技术,保证数据在任何时刻,最多有一个线程访问,以保证数据的完整性。
好处:
1.充分利用CPU的资源
2.简化编程模型
3.良好的用户体验
主线程:
1.main()方法即为主线程入口
2.产生其他子线程的线程
3.必须最后完成执行,因为它执行各种关闭动作
4.终止线程
线程:
1. 一个进程内部的一个执行单元,它是程序中的一个单一的顺序控制流程。
2. 一个进程可拥有多个并行的(concurrent)线程。
3. 一个进程中的多个线程共享相同的内存单元/内存地址空间,可以访问相同的变量和对象,而且它们从同一堆中分配对象并进行通信、数据交换和同步操作。
4. 由于线程间的通信是在同一地址空间上进行的,所以不需要额外的通信机制,这就使得通信更简便而且信息传递的速度也更快。
5. 线程的启动、中断、消亡,消耗的资源非常少。
继承Thread类创建线程
public class TestThread extends Thread { //自定义类继承Thread类 public void run() { //run()方法里是线程体 for (int i = 0; i < 10; i++) { System.out.println(this.getName() + ":" + i); //getName()方法是返回线程名称 } } public static void main(String[] args) { TestThread thread1 = new TestThread(); //创建线程对象 thread1.start(); //启动线程 TestThread thread2 = new TestThread(); thread2.start(); } }
多个线程交替执行,线程每次执行时长由CPU决定
Runnable接口创建线程
1.定义MyRunnable类实现Runnable接口
2.实现run()方法,编写线程执行体
3.创建线程对象,调用start()方法启动线程
public class TestThread2 implements Runnable { //自定义类实现Runnable接口; public void run() { //run()方法里是线程体; for (int i = 0; i < 10; i++) { System.out.println(Thread.currentThread().getName() + ":" + i); } } public static void main(String[] args) { //创建线程对象,把实现了Runnable接口的对象作为参数传入; Thread thread1 = new Thread(new TestThread2()); thread1.start(); //启动线程; Thread thread2 = new Thread(new TestThread2()); thread2.start(); } }
线程调度
线程调度指按照特定机制为多个线程分配CPU的使用权
线程优先级
1.线程优先级由1~10表示,1最低,默认优先级为5
2.优先级高的线程获得CPU资源的概率较大
线程休眠
让线程暂时睡眠指定时长,线程进入阻塞状态
睡眠时间过后线程会再进入可运行状态
public class Wait { public static void bySec(long s) { for (int i = 0; i < s; i++) { System.out.println(i + 1 + "秒"); try { Thread.sleep(1000); //线程休眠1秒(1秒=1000毫秒) } catch (InterruptedException e) { e.printStackTrace(); } } } }
线程的强制运行
public final void join()
public final void join(long mills)
public final void join(long mills,int nanos)
millis:以毫秒为单位的等待时长
nanos:要等待的附加纳秒时长
需处理InterruptedException异常
死锁及解决方案
死锁的概念
多个线程各自占有一些共享资源,并且互相等待其他线程占有的资源才能进行,而导致两个或者多个线程都在等待对方释放资源,都停止执行的情形。
因此, 某一个同步块需要同时拥有“两个以上对象的锁”时,就可能会发生“死锁”的问题。
“化妆线程”需要同时拥有“镜子对象”、“口红对象”才能运行同步块。那么,实际运行时,“小丫的化妆线程”拥有了“镜子对象”,“大丫的化妆线程”拥有了“口红对象”,都在互相等待对方释放资源,才能化妆。这样,两个线程就形成了互相等待,无法继续运行的“死锁状态”。(一下是百战程序员案例代码)
class Lipstick {//口红类
}
class Mirror {//镜子类
}
class Makeup extends Thread {//化妆类继承了Thread类
int flag;
String girl;
static Lipstick lipstick = new Lipstick();
static Mirror mirror = new Mirror();
@Override
public void run() {
// TODO Auto-generated method stub
doMakeup();
}
void doMakeup() {
if (flag == 0) {
synchronized (lipstick) {//需要得到口红的“锁”;
System.out.println(girl + "拿着口红!");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (mirror) {//需要得到镜子的“锁”;
System.out.println(girl + "拿着镜子!");
}
}
} else {
synchronized (mirror) {
System.out.println(girl + "拿着镜子!");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (lipstick) {
System.out.println(girl + "拿着口红!");
}
}
}
}
}
public class TestDeadLock {
public static void main(String[] args) {
Makeup m1 = new Makeup();//大丫的化妆线程;
m1.girl = "大丫";
m1.flag = 0;
Makeup m2 = new Makeup();//小丫的化妆线程;
m2.girl = "小丫";
m2.flag = 1;
m1.start();
m2.start();
}
}
在实际开发中,尤其是“架构设计”中,会大量使用这个模式。这就是必须掌握的内容。
IO流
字节流:二进制,可以一切文件 包括 纯文本 doc 音频、视频等等
字符流:文本文件,只能处理纯文本
输入流和输出流,差别在于出和入,是相对于程序而言的。“输入流式得到数据,输出流是输出数据”,这种说法是对的。你把问题想复杂了,输入是程序得到外部数据,输出是程序向外部传输数据,二者没专有必然的联系,都是流,差别是方向不同,也就是说,程序可以只有输入流而没有输出流,或者只有输出流而没有输入流
标签:字符 rand doc 体验 override ring size 输入 error
原文地址:https://www.cnblogs.com/zhrehe-11/p/12885301.html