线程与死锁
Java多线程实现的方式有四种
1.继承Thread类,重写run方法
2.实现Runnable接口,重写run方法,实现Runnable接口的实现类的实例对象作为Thread构造函数的target
3.通过Callable和FutureTask创建线程
4.通过线程池创建线程
前面两种可以归结为一类:无返回值,原因很简单,通过重写run方法,run方式的返回值是void,所以没有办法返回结果
后面两种可以归结成一类:有返回值,通过Callable接口,就要实现call方法,这个方法的返回值是Object,所以返回的结果可以放在Object对象中
死锁概述
线程死锁是指两个或两个以上的线程互相持有对方所需要的资源,由于synchronized的特性,一个线程持有一个资源,或者说获得一个锁,在该线程释放这个锁之前,其它线程是获取不到这个锁的,而且会一直死等下去,因此这便造成了死锁。
死锁产生的条件
互斥条件:一个资源,或者说一个锁只能被一个线程所占用,当一个线程首先获取到这个锁之后,在该线程释放这个锁之前,其它线程均是无法获取到这个锁的。
占有且等待:一个线程已经获取到一个锁,再获取另一个锁的过程中,即使获取不到也不会释放已经获得的锁。
不可剥夺条件:任何一个线程都无法强制获取别的线程已经占有的锁
循环等待条件:线程A拿着线程B的锁,线程B拿着线程A的锁。
死锁产生的条件
1、互斥条件:一个资源,或者说一个锁只能被一个线程所占用,当一个线程首先获取到这个锁之后,在该线程释放这个锁之前,其它线程均是无法获取到这个锁的。
2、请求和保持条件:进程已经保持了至少一个资源,但又提出了新的资源请求,而该资源 已被其他进程占有,此时请求进程被阻塞,但对自己已获得的资源保持不放。即使获取不到也不会释放已经获得的锁。
3、不可剥夺条件:任何一个线程都无法强制获取别的线程已经占有的锁
4、循环等待条件:线程A拿着线程B的锁,线程B拿着线程A的锁。
如何避免死锁
-
加锁顺序(线程按照一定的顺序加锁)
-
加锁时限(线程尝试获取锁的时候加上一定的时限,超过时限则放弃对该锁的请求,并释放自己占有的锁)
-
死锁检测
1 使用事务时,尽量缩短事务的逻辑处理过程,及早提交或回滚事务;
2 设置死锁超时参数为合理范围,如:3分钟-10分种;超过时间,自动放弃本次操作,避免进程悬挂;
3 优化程序,检查并避免死锁现象出现;
4 .对所有的脚本和SP都要仔细测试,在正式版本之前。
5 所有的SP都要有错误处理(通过@error)
6 一般不要修改SQL SERVER事务的默认级别。不推荐强行加锁
悲观锁(认为并发的概率大)
当我们要对数据库中的一条数据进行修改的时候,为了避免同时被其他人修改,最好的办法就是直接对该数据进行加锁以防止并发。这种借助数据库锁机制在修改数据之前锁定,再修改的方式被称为悲观并发控制(PCC)。
悲观锁的实现方式:悲观锁的实现,依靠数据库提供的锁机制。在数据库中,悲观锁的流程如下:
-
在对数据修改前,尝试增加排他锁。
-
加锁失败,意味着数据正在被修改,进行等待或者抛出异常。
-
加锁成功,对数据进行修改,提交事务,锁释放。
-
如果我们加锁成功,有其他线程对该数据进操作或者加排他锁的操作,只能等待或者抛出异常。
悲观锁涉及到的另外两个锁概念就出来了,它们就是共享锁与排它锁。共享锁和排它锁是悲观锁的不同的实现,它俩都属于悲观锁的范畴。
共享锁也属于悲观锁的一种,那么共享锁在mysql中是通过什么命令来调用呢。通过查询资料,了解到通过在执行语句后面加上lock in share mode就代表对某些资源加上共享锁了。
排它锁
排它锁与共享锁相对应,就是指对于多个不同的事务,对同一个资源只能有一把锁。
与共享锁类型,在需要执行的语句后面加上for update就可以了
对于update,insert,delete语句会自动加排它锁
共享锁(S锁):如 SELECT 语句。
乐观锁
乐观锁是相对悲观锁而言的,乐观锁假设数据一般情况下不会造成冲突,所以在数据进行提交更新的时候,才会正式对数据的冲突与否进行检测。
乐观并发控制相信事务之间的数据竞争概率非常小,因此尽可能直接操作,提交的时候才去锁定,不会产生任何锁和死锁。
- java代码--线程的死锁
- java线程安全与死锁
- Java线程面试题(02) Java线程中如何避免死锁
- 记一次简单的线程死锁调优
- java线程通信-死锁
- linux内核线程死锁或死循环(soft lockup)之后如何让系统宕机重启
- GCD 之线程死锁
- java面试题----用java代码写死锁(线程join写法)
- Java线程:并发协作-死锁
- 线程死锁测试_加锁次序导致死锁
- java 同步锁 synchronized 死锁 lock锁 jion 线程结束
- 黑马程序员_多线程技术_(线程的创建 Thread和Runnable、死锁、线程间通信、join、yield)
- 线程的死锁
- Java基础_线程_多线程_死锁
- Java线程死锁查看分析方法
- java 线程死锁的检测
- 线程同步和线程死锁
- 线程的死锁
- 线程锁 和 同步锁规则 模拟线程死锁 和Lock锁
- 自学线程之线程死锁与唤醒案例