异常
方法默认都可以自动抛出运行时异常!
自定义异常:
(1)自定义编译时异常
1、定义一个异常类继承Exception
2、重写构造器
3、在出现异常的地方用throw new 自定义对象抛出
4、编译时异常是编译阶段就报错,提醒跟家强烈,一定需要处理!
(2)自定义运行时异常
1、定义一个异常类继承RunTimeException
2、重写构造器
3、在出现异常的地方用throw new 自定义对象抛出;
4、提醒不强烈,编译时异常;
异常的作用
1、可以处理代码问题,防止程序出现异常后的死亡
2、提高程序的健壮性和安全性;
多线程
并发编程、
什么是进程?程序是静止的,运行中的程序就是进程;
1、动态性:进程是运行中的程序,要动态的占用内存,CPU和网络等资源;
2、独立性:进程与进程之间是相互独立的,彼此有自己独立的内存区域;
3、并发性:假设CPU是单核,同一个时刻其实内存中只有一个进程被执行;
并行:同一个时刻同时有多个在执行;
什么是线程?
线程是属于程序的,一个进程包括多个线程;
线程是进程中的一个独立执行单元;
线程的作用:
大型高并发技术的核心技术;
线程创建方式1:
1、继承Thread类
2、重写run()方法
3、创建一个新的线程对象
4、调用线程对象的Start()方法启动线程;
继承Thread类的优缺点:
优点:编码简单;
缺点:线程类已经继承了Thread类无法继承其他类;
线程创建方式2:
1、创建一个线程任务类实现Runnable接口
2、重写run()方法
3、创建一个线程任务对象。
4、把线程任务对象包装成线程对象
5、调用线程对象的start()方法启动线程;
实现Runnable接口的优缺点:
缺点:代码复杂一些;
优点:
线程任务类只是实现Runnable接口,可以继续继承了其他类;
同一个线程任务对象可以被包装为多个线程对象;
适合多个多个线程去共享一个资源;
实现解耦操作,线程任务代码可以被多个线程共享,线程任务代码和线程独立。
线程池可以放入实现Runable和Callable现成任务对象;
线程同步的做法:加锁
把共享资源进行上锁,每次只有一个线程进入访问资源;
在实例中,建议用this作为锁对象,此时this正好是共享资源;必须高度面向对象;
在静态方法中建议用类名.class字节码作为锁对象;
synchronized()
Lock()显示锁
lock.lock()
lock.unlock()
小结:线程安全性能差,线程不安全,性能好。
线程通信
案例:生产者与消费者模型,生产不能过剩,消费不能没有;
// 上锁;
public synchronized void fangfaming(){}
线程池
其实就是一个容纳多个线程的容器,其中的线程可以反复的使用,省去了频繁创建线程对象的操作,无序反复的创建线程,而消耗过多的资源;
1、降低资源消耗
2、提高响应时间
3、提高线程的可管理性;
callable做线程池的任务可以得到线程执行的结果;
死锁
面试题(一个必然死锁的案例):::代码题
解:定义两个线程,并发执行;
并发变量下的变量不可见问题
volatile关键字
目标:并发编程下,多个线程访问变量的不可见性问题
引入:多个线程访问共享变量,会出现一个线程修改变量的值后,其他的线程看不到最新值的情况;
变量不可见性内存语义
JMM(Java Memory Model):Java内存模型,虚拟机定义的内存模型,屏蔽了底层不同计算机的区别;
共享变量都存在于主内存中,每一个线程启动,都存在工作内存,每一个线程通过JMM访问主内存中的共享内存,存储到工作内存中,产生共享变量副本;
解决办法: 加一个锁:Synchronized,清空工作内存副本 ,再重新读取主内存中的工作内存;
加一个volatile 关键词修饰;
volatile和Synchronized的区别
volatile只能修饰实例变量和类变量,而Synchronized可以修饰方法,以及代码块;
volatile保证了数据的可见性,但是不能保证原子性(多线程进行写操作,不保证线程安全);Synchronized是一种排他机制;
原子性
一批操作是一个整体,要么所有的操作都会成功,要么所有的操作都失败;
volatile只能保证线程间变量的可见性,但是不能保证变量操作的原子性;
原子性的保证:加锁
原子类:
原子性Integer,可以实现原子更新操作;从而实现线程安全!
加锁机制的性能价差;
原子类CAS(比较再交换)机制实现线程安全!是现代CPU广泛支持的一种对内存中的共享数据进行操作的一种特殊指令。
CAS机制使用了三个机制:内存地址V,,。
Lambda表达式
作用:核心目的是为了简化匿名内部类的代码写法;
Lambda表达式不能简化所有匿名内部类的写法;只能简化函数式接口(FunctionalInterface)的匿名内部类写法;
1、首先是接口;
2、接口只有一个抽象方法;
Lambda进一步的简化:
Lambda表达式 方法引用
采用“::”
方法引用的四种形式:
(1)静态方法的引用;
被引用的方法的参数列表要和函数式接口中的抽象方法的参数列表一样;
(2)实例方法的引用;
格式 对象::实例方法
(3)特定类型方法的引用;
特定类型:String,任何类型;
格式,特定类型::方法
(4)构造器引用;
格式: 类名::new
Stream流
作用:用来解决已有集合/数组类库存在的弊端;
能解决的问题:
1、用来解决已有集合/数组API存在的弊端;
2、采用Stream流来简化集合与数组的操作;
Stream流的常用API
Stream流的加工方法
map():加工
concat():合并流
函数拼接与终结方法
终结方法:foreach和count
函数拼接:filter、limit、skip、map、concat
收集Stream流:把Stream流的数据转化为集合;
stream的作用是:把集合转换成一根传送带,借用stream流的强大功能进行的操作。但是实际开发中数据最终的形式还是应该是集合,最终stream流操作完毕以后还是要转换成集合这就是收集stream流。
listname.collect(Collectors.toSet());
可以借助构造器引用申明转换为数组类型;
Stream流 是手段,但是集合 才是最终目标;
标签:变量,Stream,对象,死锁,线程,内存,发包,多线程,方法 From: https://www.cnblogs.com/kuangmeng/p/18100190