的概念
“死锁”指的是:
多个线程各自占有一些共享资源,并且互相等待其他线程占有的资源才能进行,而导致两个或者多个线程都在等待对方释放资源,都停止执行的情形。
因此, 某一个同步块需要同时拥有“两个以上对象的锁”时,就可能会发生“死锁”的问题。下面案例中,“化妆线程”需要同时拥有“镜子对象”、“口红对象”才能运行同步块。那么,实际运行时,“小丫的化妆线程”拥有了“镜子对象”,“大丫的化妆线程”拥有了“口红对象”,都在互相等待对方释放资源,才能化妆。这样,两个线程就形成了互相等待,无法继续运行的“死锁状态”。
【示例1】死锁示例
class Lipstick{
}
class Mirror{
}
class Makeup extends Thread {
int flag;
String girl;
static Lipstick lipstick=new Lipstick();
static Mirror mirror= new Mirror();
@Override
public void run() {
// TODO Auto-generated method stub
doMakeup();
}
void doMakeup(){
if(flag==0){
synchronized (lipstick) {
System.out.println(girl+"拿着口红!");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (mirror) {
System.out.println(girl+"拿着镜子!");
}
}
}
else{
synchronized (mirror) {
System.out.println(girl+"拿着镜子!");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (lipstick) {
System.out.println(girl+"拿着口红!");
}
}
}
}
}
public class TestDeadLock {
public static void main(String[] args) {
Makeup m1 = new Makeup(); m1.girl="大丫"; m1.flag=0;
Makeup m2 = new Makeup(); m2.girl="小丫"; m2.flag=1;
m1.start();
m2.start();
}
}
图1 线程互相等待“资源”而处于“停滞”状态
死锁的解决方法
死锁是由于“同步块需要同时持有多个对象锁造成”的,要解决这个问题,思路很简单,就是:
同一个代码块,不要同时持有两个对象锁。
如上面的死锁案例,修改成示例2所示。
【示例2】死锁问题的解决(修改示例1中doMakeup方法)
void doMakeup(){
if(flag==0){
synchronized (lipstick) {
System.out.println(girl+"拿着口红!");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
synchronized (mirror) {
System.out.println(girl+"拿着镜子!");
}
}
else{
synchronized (mirror) {
System.out.println(girl+"拿着镜子!");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
synchronized (lipstick) {
System.out.println(girl+"拿着口红!");
}
}
}
示例2 运行效果图
示例2 运行效果图
「全栈Java笔记」是一部能帮大家从零到一成长为全栈Java工程师系列笔记。笔者江湖人称 Mr. G,10年Java研发经验,曾在神州数码、航天院某所研发中心从事软件设计及研发工作,从小白逐渐做到工程师、高级工程师、架构师。精通Java平台软件开发,精通JAVAEE,熟悉各种流行开发框架。
笔记包含从浅入深的六大部分:
A-Java入门阶段
B-数据库从入门到精通
C-手刃移动前端和Web前端
D-J2EE从了解到实战
E-Java高级框架精解
F-Linux和Hadoop