目录
线程
线程:
就是进程中一个负责程序执行的控制单元执行路径
一个进程中可以多执行路径,称之为多线程。
一个进程中至少要有一个线程。开启多个线程是为了同时运行多部分代码。
其实应用程序的执行都是cpu在做着快速的切换完成的。这个切换是随机的
守护线程
守护线程:(后台线程)//t1.setDaemon(true)//设置为守护线程
当其他线程结束时,守护线程也结束
线程安全
线程安全:如果你的代码在多线程和单线程的执行状态下永远都能获得一样的结果,那这个代码就是线程安全的。
线程安全问题:
线程安全问题产生的原因:
1,多个线程在操作共享的数据。
2,操作共享数据的线程代码有多条。
当一个线程在执行操作共享数据的多条代码过程中,其他线程参与了运算。就有可能会导致线程安全问题的产生。
如:println与i--连用。
解决思路:
就是将多条操作共享数据的线程代码封装起来,当有线程在执行这些代码的时候,其他线程时不可以参与运算的。
必须要当前线程把这些代码都执行完毕后,其他线程才可以参与运算。
在Java中,用同步代码块就可以解决这个问题。
不变的:
绝对线程安全:CopyOnWriteArrayList,CopyOnWriteArraySet
线程同步
线程同步:同步时,其他人不能对其进行操作(不可使用)同步的使用可以保证在多线程运行的环境中,程序不会产生设计之外的错误结果。同步的实现方式有两种,同步方法和同步块,这两种方式都要用到synchronized关键字。
同步关键字:synchronized(可以修饰方法或对象)
即有synchronized关键字修饰的方法。 由于java的每个对象都有一个内置锁,当用此关键字修饰方法时, 内置锁会保护整个方法。在调用该方法前,需要获得内置锁,否则就处于阻塞状态。
同步的好处:解决了线程的安全问题.
同步的弊端:相对降低了效率,因为同步外的线程的都会判断同步锁。
同步的前提:同步中必须有多个线程并使用同一个锁。
同步代码块
同步代码块的格式:
synchronized (对象){
需要被同步的代码;
}
同步函数:
同步函数的使用的锁是this;
静态的同步函数使用的锁是该函数所属字节码文件对象(整个类),可以用getclass方法获取,也可以用当前类名.class表示。
同步函效和同步代码块的区别:
同步函数的锁是固定的this。同步代码块的锁是任意的对象。 建议使用同步代码块。
注: synchronized关键字也可以修饰静态方法,此时如果调用该静态方法,将会锁住整个类。 同步是一种高开销的操作,因此应该尽量减少同步的内容。通常没有必要同步整个方法,使用synchronized代码块同步关键代码即可。
注意:一个锁中只能有一个线程运行,但有可能有多个线程存活;
死锁:
当一组进程或线程的每一个都在等待一个只有该进程才能引起的事件时,那这组 进程或线程死锁。
死锁的根本原因:
1)是多个线程涉及到多个锁,这些锁存在着交叉,所以可能会导致了一个锁依赖的闭环;
2)默认的锁申请操作是阻塞的。
死锁常见场景:
1.同步的嵌套;
所以要避免死锁,就要在一遇到多个对象锁交叉的情况,就要仔细审查这几个对象的类中的所有方法,是否存在着导致锁依赖的环路的可能性。