多线程学习二之线程之间实现同步

上篇博客回顾:

1.线程与进程区别:进程是所有线程的集合,线程是进程中的一条执行路径

2.为什么要使用多线程:提高程序效率

3.多线程应用场景:提高程序运行效率,比如迅雷 分批处理数据

4.多线程创建方式:三种创建方式 继承Thread 、实现Runnable接口、匿名内部类

5.获取线程对象以及名称:查看Api

6.线程运行状态:新建状态、运行状态、就绪状态、阻塞状态、死亡状态

这篇博客记录线程之间实现同步学习记录

线程安全

synchronized用法

死锁

一、先看看什么是线程安全

1.为什么有线程安全问题 什么时候出现线程安全问题?

我们先来看下案例:

多线程学习二之线程之间实现同步

多线程学习二之线程之间实现同步

运行结果:

多线程学习二之线程之间实现同步

线程一和线程二同时抢口香糖时会重复出售

结论:当多个线程同时共享同一个全局变量或静态变量,做写的操作时可能会发生数据冲突问题也就是线程安全问题。但是做读操作是不会发生数据冲突问题。

二、线程安全解决方案

1.使用同步代码块

将可能会发生线程安全问题的代码,给包括起来。

synchronized(同一个数据){

 可能会发生线程冲突问题

}

案列

多线程学习二之线程之间实现同步

2.同步函数

在方法上修饰synchronized称为同步函数 值得注意的是同步函数使用的是this锁

案列:

多线程学习二之线程之间实现同步

3.静态同步函数

方法上加上static关键字,使用synchronized 关键字修饰。

静态的同步函数使用的锁是当前类名.class 

多线程学习二之线程之间实现同步

4.使用锁(lock)

jdk1.5 之后,并发包中新增了 Lock 接口(以及相关实现类)用来实现锁功能,Lock 接口提供了与 synchronized 关键字类似的同步功能,但需要在使用时手动获取锁和释放锁。

三、synchronized和lock比较

Lock 接口可以尝试非阻塞地获取锁当前线程尝试获取锁。如果这一时刻锁没有被其他线程获取到,则成功获取并持有锁。

*Lock 接口能被中断地获取锁 synchronized 不同,获取到锁的线程能够响应中断,当获取到的锁的线程被中断时,中断异常将会被抛出,同时锁会被释放。

Lock 接口在指定的截止时间之前获取锁,如果截止时间到了依旧无法获取锁,则返回

四、多线程死锁

案列:

多线程学习二之线程之间实现同步

多线程学习二之线程之间实现同步

多线程学习二之线程之间实现同步

输出结果:

多线程学习二之线程之间实现同步

思考

1.flag为true时,先拿到obj锁再拿到this锁,才执行代码 

2.flag为false时,先拿到this锁再拿到obj锁,才执行代码

 3.两个线程同时执行时flag为true线程去拿flag为false的obj锁是会产生死锁

结论 :导致多线程死锁的原因是同步中嵌套同步,导致锁无法释放