多线程的知识点总结


进程和线程
进程:正在运行的程序,占用内存和CPU资源
线程:是进程中的一条执行路径,
进程是由线程组成,如果一个进程一个线程都没有,则该进程也会随着结束
一个进程中可以有多个条线程,称之为多线程程序

实现多线程程序
方式一:继承Thread类
步骤:
1.自定义一个类继承Thread类
2.重写Thread类中的run方法
public void run() {

}
3.在测试类中创建自定义类对象
4.调用start()方法启动线程

方式二:实现Runnable接口
步骤:
1.自定义一个类实现Runnable接口
2.重写接口中的run方法
3.在测试类中创建自定义类对象
4.创建Thread类的对象,将自定义类对象当做构造方法参数进行传递
5.使用Thread类的对象调用start()启动线程

面试题:两种创建新线程的方式的区别
1、实现Runnable接口的方式避免了单一继承的局限性
继承Thread类有单一继承的局限性,它已经有父类就不使用这种方法了
2、实现Runnable接口的方式将线程任务和线程启动进行分类

多线程执行的特点
1、CPU在多条线程之间进行高速来回随机切换
CPU执行速度特别快
多条线程在抢夺CPU的执行权
执行是很随机的,没有规律,看到执行的结果每次都不太一样
2、我们看到的结果称之为交替执行,专业的叫法是并发执行
3、多条线程执行是互不干扰的,互相独立的


设置和获取线程名称
线程没有设置名称也有默认名称:
普通线程:Thread-x,x是变量,从0开始
主线程:main

设置名称:
1、调用setName()方法设置
my1.setName("高铁");
2、编写一个带字符串参数的构造
public MyThread(String name) {
super(name);
}
获取名称
String getName()

线程的优先级
范围:1~10之间
优先级越高的线程抢占到CPU的几率也高,但是不是绝对的


方法重写的原则:一大两同两小
方法重写一般子类和父类方法的方法声明一致,但是方法声明其实也是可以不完全一致的,遵循以下原则:
一大:子类方法的权限修饰大于等于父类方法的权限修饰符
public > protected > 默认 > private
两同:
1、方法名要完全相同
2、参数里列表要完全相同
两小
1、子类方法的返回值类型必须小于等于父类方法的返回值类型
只针对引用类型有效,对基本类型无效
如果返回值类型是基本类型或者是void,那么也必须一致
2、子类方法抛出的异常要少于等于父类方法的异常,父类方法如果没有抛异常则子类绝对不能抛,只能处理
子类方法抛出的异常要小于等于父类方法的异常


线程状态
NEW:新建
至今尚未启动的线程处于这种状态。
RUNNABLE:运行状态
正在 Java 虚拟机中执行的线程处于这种状态。
BLOCKED:阻塞和就绪(没有CPU的执行权)
受阻塞并等待某个监视器锁的线程处于这种状态。
WAITING:无限等待(调用wait())
无限期地等待另一个线程来执行某一特定操作的线程处于这种状态。
TIMED_WAITING:计时等待(调用wait(long time))
等待另一个线程来执行取决于指定等待时间的操作的线程处于这种状态。
TERMINATED:死亡
已退出的线程处于这种状态。

线程同步
线程安全问题产生的原因:
1、多线程
2、有共享数据,代码有多条
3、多线程操作共享数据

解决:
1、使用同步代码块
格式:
synchronized(锁对象){

}
使用同步代码块包裹起来的代码,同一时刻最多只会有一条线程执行,不可能同时有多条线程执行
在执行同步代码块的时候,先要判断锁是否存在,如果存在则获取锁,直到执行到同步代码块的最后
碰到右大括号(})再释放锁,释放了之后其他线程才能抢锁,谁抢到谁继续执行同步代码块中的代码,没
抢到的只能在同步代码块之外进行等待。

锁对象可以是任意对象,但是要求必须是同一个对象,多个线程看到的这个锁的地址值是相同的

2、使用同步方法:在方法声明上加synchronized
同步方法的锁虽然看不到,但是其实是有默认锁的
非静态同步方法:this
静态同步方法:当前类的字节码对象(当前类名.class)

3、Lock锁

面试题:
ArrayList和Vector的区别
1、ArrayList是不同步的(非同步的),没有加同步(同步代码块和同步方法),效率高,但是它在多线程不安全
Vector是同步的,加了同步锁,效率低,但是它是线程安全的
2、ArrayList是后期归为单列集合体系的,方法名称都很规范,很简洁
Vector是单列集合体系之前出现的,方法名称都不够规范,不够简洁
ArrayList是替代Vector的,即使是多线程情况下也不使用Vector,以后Vector可能在面试的时候才用到

StringBuilder和StringBuffer的区别
StringBuilder不同步的,效率高,不安全
StringBuffer是同步的,效率低,安全

如果是单线程使用StringBuilder
如果是多线程使用StringBuffer
HashMap和Hashtable的区别
1、HashMap不同步的,效率高,不安全
Hashtable是同步的,效率低,安全
2、HashMap可以存储null键和null值
Hashtable不能存储null键和null值

HashMap是替代Hashtable的,即使是多线程情况下也不使用Hashtable,以后Hashtable可能在面试的时候才用到


线程通信
应用等待唤醒机制
wait():无限等待
notify():随机唤醒一个正在等待的线程
notifyAll():唤醒所有正在等待的线程
生成者和消费者案例

 

面试题:
sleep和wait的区别
1、sleep是Thread类中的静态方法,sleep方法必须传递时间参数
wait是Object类中的非静态方法,可以传递时间参数也可以不传递

2、sleep可以在同步中使用,也可以在非同步中使用
wait必须在同步中使用,而且必须被锁对象所调用

3、sleep在同步中使用不会释放锁,会抱着锁睡觉
wait在同步中使用会释放锁

posted @ 2019-12-24 10:24  旧城孤影  阅读(408)  评论(0编辑  收藏  举报