在千锋“逆战”学习第30天周总结

在千锋"逆战”学习第30天,
每个人生阶段都需要努力去扮好自己的角色,越努力越轻松,越坚强越幸运!
加油!

1.异常

概念:程序在运行过程中出现的特殊情况。
异常处理的必要性:任何程序都可能存在大量的未知问题丶错误;
如果不对这些问题进行正确处理,则可能导致程序的中断,造成不必要的损失。

2.异常的分类

I-Throwable:可抛出的,一切错误或异常的父类。位于java.lang包中。
|-Error:JVM、硬件、执行逻辑错误,不能手动处理。
|-Exception:程序在运行和配置过程中产生的问题,可处理。
|-RuntimeException:运行时异常,可处理,可不处理。
|-CheckedException:受查异常,必须处理。

3.异常的产生:

自动抛出异常:当程序运行时,遇到不符合规范的代码或结果时,会产生异常。
手动抛出异常:语法:throw new 异常类型(“实际参数”);
产生异常结果:相当于遇到return语句,导致程序因异常而终止;

4.异常的传递

异常的传递:按照方法的调用链反向传递,如始终没有处理异常,最终会由JVM进行默认异常处理(打印堆栈跟踪信息)
受查异常:throws 声明异常,修饰在方法参数列表后端。
运行时异常:因可处理可不处理,无需声明异常

5.异常的处理
I.	try{
//可能出现异常的代码	
}catch(Exception e){
    //捕获异常后,对异常处理的相关代码。处理方案:
    1、自定义2、printStackTrace();3.getMessage();
}finally{
   //无论是否出现异常,都需要执行的代码。常用于释放资源.
}
II.	常见异常处理结构
(1)	try{ }catch(){}
(2)	try{}catch(){}catch(){}
(3)	try{}catch(){}finally{}
(4)	Try{}catch(){}catch(){}finally{}
(5)	try{}finally{}
6.自定义异常
I.	继承Exception(受查异常)或Exception的子类。常用RuntimeException.(运行时异常)
II.	必要提供的内容
(1)	无参构造方法
(2)	String message参数的构造方法。定义异常原因信息
7.异常方法覆盖
I. 方法名、参数列表、返回值类型必须和父类相同
II. 子类的访问修饰符和父类相同或比父类更宽泛
III. 子类中的方法,不能抛出比父类更宽泛的异常。
8.
方法执行中字节码操作指令
I.反编译:javap -verbose 文件名称(是.class)  >  自定义文件名称.bytecode

2.线程

1.进程

什么是进程
程序是静止的,只有程序运行时才能称为进程。
单核CPU在任何时间点上只能运行一个进程,宏观并行,微观串行。

2.线程

什么是线程线程,又称轻量级进程,程序中的一个顺序控制流程,同时也是CPU的基本调度单位。进程由多个线程组成,彼此间完成不同的工作,交替执行,称为多线程。

3.线程的组成

I.CPU时间片
II. 运行数据:
(1).堆空间:存储线程需要使用的对象,多个线程可以共享堆中的对象
(2).栈空间:存储线程需要使用的局部变量,每个线程都拥有独立的栈

4.线程的创建
I. 继承Thread类,自定义类变成线程类
II. 实现Runnable接口,赋予自定义类线程任务的能力。
III. 实现Runnable接口,不影响类继承,更灵活。
IV. 线程创建后,需要调用start();方法,来启动线程,由JVM调用run()方法。
直接调用run()方法并不是线程的启动。
5.线程的状态(基本)

在这里插入图片描述

6.线程常见方法

I. 休眠 sleep(long millis);
(1).当前线程主动休眠 millis毫秒,进入有限期等待!
II. 放弃 yield();
(1).当前线程主动放弃时间片,回到就绪状态,竞争下一次时间片
III. 结合 join();
(1).允许其他线程加入到当前线程中,当前线程进入无限期等待!

7.线程的状态(等待)

在这里插入图片描述

8、线程安全的问题

I. 当多线程并发访问临界资源时,如果破坏了原子操作,可能会导致数据不一致。
II. 临界资源:共享资源(同一对象、堆空间),一次仅允许一个线程使用,才可保证其正确性
III.原子操作:不可分割的多步操作,被视作为一个整体,其顺序和步骤不能打乱或缺省。

9、synchronized 同步锁

I.每个对象都有一个互斥锁标记,用来分配给线程。
II.只有持有对象互斥锁标记的线程,才能进入对该对象加锁的同步操作中(同步方法、同步代码块)。
III.只有线程退出同步操作时,才会释放相应的锁标记

10、同步方式

I.同步代码块
(1). synchronized(临界资源对象){
//原子操作
}
II. 同步方法
(1)synchronized 返回值类型 方法名成(参数列表){//原子操作

11.线程的状态(阻塞)

在这里插入图片描述

12.同步规则

I. 只有在调用包含同步代码块的方法或者是同步方法时,才需要对象的锁标记
II. 如果调用的是不包含同步代码块的方法或普通方法时,则不需要锁标记,直接调用即可。
III. 已知线程安全的内容:StringBuffer、Vector、Hashtable

13.死锁、生产者与消费者

死锁
当一个线程拥有A对象锁标记,并等待B对象锁标记,同时第二个线程拥有B对象锁标记,并等待A对象锁标记时,产生死锁。
一个对象可同时拥有多个对象的锁标记,当线程阻塞时,不会释放已经拥有的锁标记,由此可能造成死锁。
生产者、消费者
若干个生产者在生产产品,这些产品将提供给若干个消费者去消费,为了使生产者和消费者能并发执行,在两者之间设置一个能储存多个产品的缓冲区,生产者将生产的产品放入缓冲区,消费者从缓冲区取走产品进行消费,显然生产者和消费者之间必须保持同步,既不允许消费者到一个空缓冲区中取产品,也不允许生产者向一个满的缓冲区放入产品。

14.线程通信

I. 等待
(1) wait();
(2) 必须在对obj(对象)加锁的同步代码块(或同步方法)中,在一个线程执行期间,调用了obj.wait(),该线程会释放所拥有的锁标记。同时,进入到obj的等待队列中。等待唤醒
II. 通知(唤醒)
(1).notify();notifyAll();
(2).必须在对obj加锁的同步代码块(或同步方法)中,从obj的Waiting(等待队列)中随机释放一个或全部线程。对自身线程无影响。

高级多线程

线程池概念

现有问题
线程是宝贵的内存资源,单个线程约占1MB空间,过多分配易造成内存溢出
频繁的创建及销毁进程会增加虚拟机回收频率,资源开销,造成程序性能下降
线程池
线程容器,可设定线程分配的容量上限
将预先创建的线程对象存入池中,并重复用线程池中的线程对象
避免频繁的创建和销毁
将任务提交给线程池,由线程池分配线程、运行任务,并在当前任务结束后复用线程。

在这里插入图片描述

获取线程池

Executor:线程池的顶级接口
ExecutorService:线程池接口,可通过submit(Runnable task)提交任务代码
Executors工厂类:通过此类可以获得一个线程池
通过newFixedThreadPool(int nThread)获取固定数量的线程池。参数:指定线程池中线程的数量
通过newCachedThreadPool()获得动态数量的线程池,如不够创建新的,没有上限

Callable接口

public interface Callable{
public V call() throws Exception;
}
JDK5加入,与Runnable接口类似,实现之后代表一个线程任务。
Callable具有泛型返回值、可以声明异常

Future接口

概念:异步接收ExecutorService.submit()所返回的状态结果,当中包含了call()的返回值

方法:V get()以阻塞形式等待Future中的异步处理结果(call()的返回值)

Lock接口

JDK5加入,与synchronized比较,显式定义,结构更灵活

提供更多实用性方法,功能更强大,性能更优越

常用方法:
void lock()//获取锁,如锁被占用,则等待
boolean tryLock()//尝试获取锁
void unlock()//释放锁

重入锁
ReentrantLock:Lock接口的实现类,与sychronized一样具有互斥锁功能。

读写锁
ReentrantReadWriteLock:
一种支持一写多读的同步锁,读写分离,可分别分配读锁,写锁。
支持多次分配读锁,使多个读操作可以并发执行。

互斥规则:
写-写:互斥,阻塞
读-写:互斥,读阻塞写、写阻塞读
读-读:不互斥、不阻塞

在读操作远远高于写操作的环境中,可在保障线程安全的情况下,提高运行效率。

线程安全的集合

Collections中的工具方法
Collections工具类中提供了多可以获得线程安全集合的方法
public static Collection synchronizedCollection(Collection c)
public static List synchronizedList(List list)
public static Set synchronizedSet(Set s)
public static <K,V>Map<K,V>synchronizedMap(Map<K,V> m)
public static SortedSetsynchronizedSortedSet(SortedSet s)
publicstatic<K,V>SortedMap<K,V>synchronizedSortedMap(SortedMap<K,V> m)
JDK1.2提供,接口统一、维护性高,但性能没有提升,均以synchronized实现

CopyOnWriteArrayList
线程安全的ArrayList,加强版读写分离
写有锁,读无锁,读写之间不阻塞,优于读写锁
写入时,先copy一个容器副本,再添加新元素,最后替换引用
使用方法与ArrayList无异

CopyOnWriteArraySet
线程安全的Set,底层使用CopyOnWriteArrayList实现
唯一不同在于,使用addIfAbsent()添加元素,会遍历数组
如存在元素,则不添加(扔掉副本)

ConcurrentHashMap
初始容量默认为16段(Segment),使用分段锁设计
不对整个Map加锁,而是为每个Segment加锁
当多个对象存入同一个Segment时,才需要互斥
最理想状态为16个对象分别存入16个Segment,并行数量16
使用方式与HashMap无异

Queue接口(队列)

Collection的子接口,表示队列FIFO(First In First Out 先进先出)

常用方法:
抛出异常:
boolean add(E e)//顺序添加一个元素(到达上限后,再添加则会抛出异常)
E remove()//获得第一个元素并移除(如果队列没有元素,则抛出异常)
E element()//获得第一个元素但不移除(如果队列没有元素,则抛出异常)

返回特殊值(推荐使用):
boolean offer(E e)//顺序添加一个元素(到达上线后,在添加则会返回false)
E poll()//获得第一个元素并移除(如果队列没有元素时,则返回null)
E keep()//获得第一个元素但不移除(如果队列没有元素时,则返回null)

ConcurrentLinkedQuene
线程安全,可高效读写的队列,高并发下性能最好的队列
无所,CAS比较交换算法,修改的方法包括三个核心参数(V,E,N)
V:要更新的变量
E:预期值
N:新值
只有当V==E时,V=N;否则表示已被更新过,则取消当前操作

BolckingQuene接口(阻塞队列)
Quene的子接口,阻塞的队列,增加了两个线程状态为无限期等待的方法

方法:
void put(E e)//将指定元素插入此队列中,如果没有可用空间,则等待
E take()//获取并移除此队列头部元素,如果没有可用元素,则等待

可用于解决生产者、消费者问题

阻塞队列
ArrayBlockingQuene:
数组结构实现,有界队列(手工固定上限)

LinkedBlockingQuene:
链表结构实现,无界队列(默认上限Integer.MAX_VALUE)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值