内部类:类中类
格式: class A{
class B{
...
}
}
内部类可以直接使用外部类的成员
外部类不能直接使用内部类的成员
匿名内部类:
new 父类/接口(){
重写方法
}.重写的方法;
异常
分为两类
Throwable:
Error:严重错误,需要事先避免。
Exception:表示异常,异常产生后可以通过代码纠正。
编译时期的异常:代码在写的时候,自动编译,报错
RuntimeException:运行时候的异常,代码写上去没有语法错误,但是运行会出错
异常的创建
throw new 异常对象
异常的处理
编译异常需要在方法声明处写上throws
运行时的异常似乎不用
finally
一定会执行的代码,不管会不会有异常。防止下面没catch到,在try中的代码块就直接返回给虚拟机了,下面的代码没有执行
使用场景:关闭资源
异常对象的方法
public String getMessage():获取异常的描述信息,原因
public String toString():获取异常的类型和异常的描述信息
public voidprintStackTrace():打印异常的跟踪栈信息并输出到控制台
继承中的异常处理
- 父类中的方法抛出异常后,子类重写的方法可以抛出父类方法异常的子类
- 父类方法没有抛异常,子类重写的方法不能抛出异常
多任务
并行:指两个或多个事件在同一时刻发生(执行)
并发:指两个或多个事件在同一时刻交替发生(执行)
创建线程方式
方式一:
定义一个类,继承Thread类
重写Thread中的run方法
创建线程类对象,调用start方法开启线程
注意:
调用start方法,开启新的线程,并执行run方法
调用run方法,只是简单的调用方法而已,不会开启新线程
方式二:
创建一个类,实现Runnable接口
覆盖重写run方法
创建实现类对象
创建Thread类的对象,传递Runnable接口的实现类对象
Thread类的对象调用start方法,开启线程
匿名内部类方法创建线程
new Thread(new Runnable(){
@override
public void run(){
System.out.println("线程执行")
}
}).start();
线程安全
解决共享数据出错方案
同步代码块
synchronized(任意对象){
...
}
{}中写所有需要操作共享数据的代码
任意对象:对象监视器
锁对象可以是任意对象,必须保证唯一
同步方法
修饰符 synchronized 返回值类型 方法名称 (参数列表){
...
}
Lock接口
使用自带的实现类ReentrantLock类,调用lock()和unlock()方法上锁和释放锁
使用方式:
创建Lock接口的实现类对象,作为锁对象,因为定义在成员位置,所以是唯一的
Lock lock = new ReentrantLock();
但要注意一定要释放锁(finally代码块)
线程状态(生命周期)
- NEW:新建Thread子类(对象)
- RUNNABLE:调用 start()
- BLOCKED:线程没抢到锁,进入blocked状态(阻塞状态),抢到锁进入runnable状态
- WAITTING:无限等待。RUNNABLE状态时调用wait()方法,释放锁。进入WAITTING状态,调用notify()唤醒,然后跟其他线程进行抢锁。获取到锁进入RUNNABLE状态,没有锁进入BLOCKED状态
- TIMED WAITTING:限速等待。RUNNABLE状态时调用wait(毫秒值)方法,释放锁。进入有限等待状态。时间到后如果拿到锁,回到运行状态。RUNNABLE状态时调用sleep(毫秒值)方法,进入限时等待状态。如果RUNNABLE有锁,那么限时等待时完后也会有锁。notify()唤醒的话,都要重新抢锁。
- TERMINATED:run方法执行完毕
ThreadLocal类
java.lang.ThreadLocal 该类提供了线程局部(thread-local) 变量,用于在当前线程中共享数据。ThreadLocal工具
类底层就是相当于一个Map,key存放的当前线程,value存放需要共享的数据。
作用: 实现线程共享局部变量
内部使用Map集合,Map集合有2个泛型,K: 键的类型,V代表值的类型
ThreadLocal
成员方法
public void set(T t)
: 给当前线程对象,绑定一个T类型的变量t。相当于Map集合map.put(Thread.currentThread,t)
public T get()
:获取当前线程对象上,绑定的值。相当于Map集合map.get(Thread.currentThread)
public T remove()
:删除当前线程对象上绑定的值。相当于Map集合map.remove(Thread.currentThread)
示例代码
public class Demo02ThreadLocal {
public static void main(String[] args) {
//创建ThreadLocal对象
ThreadLocal<String> tl = new ThreadLocal<>();
//获取当前线程绑定的值: 以当前main线程作为键,获取绑定的值
String s = tl.get();
System.out.println(s);//null
//给当前main线程,绑定值"hello Threadlocal"
tl.set("hello Threadlocal");
s = tl.get();
System.out.println(s);//hello Threadlocal
//创建SubThread类的对象
//创建这样一个实现了Thread类的实现类对象即创建了一个线程,所以SubThread类中run方法跑出来的是null
SubThread st = new SubThread(tl);
//开启线程
st.start();
}
}
SubThread类代码
public class SubThread extends Thread {
private ThreadLocal<String> tl;
public SubThread(ThreadLocal<String> tl) {
this.tl = tl;
}
@Override
public void run() {
//获取当前线程对象上绑定的值
String str = tl.get();
System.out.println("run...."+str);//run....null
tl.set("abc");
str = tl.get();
System.out.println("run...."+str);//run...abc.
}
}
Collection集合
Collection是所有单列集合的父接口,因此在Collection中定义了单列集合(List和Set)通用的一些方法,这些方法可
用于操作所有的单列集合。常用方法如下:
public boolean add(E e) : 把给定的对象添加到当前集合中 。
public boolean contains(Object obj) : 判断当前集合中是否包含给定的对象。
public boolean isEmpty() : 判断当前集合是否为空。
public int size() : 返回集合中元素的个数。
public boolean remove(E e) : 把给定的对象在当前集合中删除。注意,只删除一个元素,有重复的只删除第一个
public Object[] toArray() : 把集合中的元素,存储到数组中
public void clear() :清空集合中所有的元素。
tips: 有关Collection中的方法可不止上面这些,其他方法可以自行查看API学习。
遍历集合Iterator迭代器
Iterator接口的常用方法如下:
- public E next() :返回迭代的下一个元素。
- public boolean hasNext() :如果仍有元素可以迭代,则返回 true。
注意
- 在进行集合元素获取时,如果集合中已经没有元素了,还继续使用迭代器的next方法,将会抛出
java.util.NoSuchElementException没有集合元素异常。- 在进行集合元素获取时,如果添加或移除集合中的元素 , 将无法继续迭代 , 将会抛出
ConcurrentModificationException并发修改异常.
增强for
增强for循环(也称for each循环)是JDK1.5以后出来的一个高级for循环,专门用来遍历数组和集合的。它的内部原
理其实是个Iterator迭代器,所以在遍历的过程中,不能对集合中的元素进行增删操作。
格式:
for(元素的数据类型 变量 : Collection集合or数组){
//写操作代码
}
其实跟Python的for差不多。。。。
泛型
跟C++差不多