A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© wudongzhe 中级黑马   /  2013-5-1 23:20  /  1583 人查看  /  5 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 吴东泽 于 2013-5-2 23:22 编辑

当在方法声明的时候用到了关键字synchronized  后再在方法体中用synchronized就会发生死锁的情况呢?死锁还有在哪些情况导致? 平时写线程的时候要都注意些那些方面呢?

评分

参与人数 1技术分 +1 收起 理由
黄玉昆 + 1

查看全部评分

5 个回复

倒序浏览
以下是以前的摘抄一些笔记,希望可以帮助到你。
操作系统中有若干进程并发执行,它们不断申请、使用、释放系统资源,虽然系统的进
程协调、通信机构会对它们进行控制,但也可能出现若干进程都相互等待对方释放资源才能
继续运行,否则就阻塞的情况。此时,若不借助外界因素,谁也不能释放资源,谁也不能解
除阻塞状态。根据这样的情况,操作系统中的死锁被定义为系统中两个或者多个进程无限期
地等待永远不会发生的条件,系统处于停滞状态,这就是死锁。
产生死锁的原因主要是:
(1) 因为系统资源不足。
(2) 进程运行推进的顺序不合适。
(3) 资源分配不当等。
如果系统资源充足,进程的资源请求都能够得到满足,死锁出现的可能性就很低,否则
就会因争夺有限的资源而陷入死锁。其次,进程运行推进顺序与速度不同,也可能产生死锁。
产生死锁的四个必要条件:
(1) 互斥条件:一个资源每次只能被一个进程使用。
(2) 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
(3) 不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺。
(4) 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。
这四个条件是死锁的必要条件,只要系统发生死锁,这些条件必然成立,而只要上述条件之
一不满足,就不会发生死锁。
死锁的解除与预防:
理解了死锁的原因,尤其是产生死锁的四个必要条件,就可以最大可能地避免、预防和
解除死锁。所以,在系统设计、进程调度等方面注意如何不让这四个必要条件成立,如何确
定资源的合理分配算法,避免进程永久占据系统资源。此外,也要防止进程在处于等待状态
的情况下占用资源。因此,对资源的分配要给予合理的规划

评分

参与人数 1技术分 +1 收起 理由
张熙韬 + 1

查看全部评分

回复 使用道具 举报
死锁就是操作系统中,共同资源分配不当导致的。只要你避免这个,一般就没有问题。比如现在有3个线程,每个线程需要两个打印机。现在有三个打印机,每个线程都分了一个,但是还缺一个,却没有打印机了。因而就不能继续运行下去,从而导致死锁。只要避免这样就可以了
回复 使用道具 举报
首先要明白死锁的原因,我有一个苹果,你有一个苹果,我只想要你手里的苹果来达到2个苹果,你也只想要我手里的苹果来达到2个苹果,我们互不相让,一直僵持,就导致了死锁。
正确使用synchronized是为了保证线程的安全,避免发生死锁。
回复 使用道具 举报
高正新 发表于 2013-5-2 10:15
首先要明白死锁的原因,我有一个苹果,你有一个苹果,我只想要你手里的苹果来达到2个苹果,你也只想要我手 ...

我也是这么理解的,这种理解很形象啊。
回复 使用道具 举报
本帖最后由 余雷 于 2013-5-2 11:22 编辑

通常出现的死锁都有哪些呢?
    (1)忘记释放锁
[void data_process()  
{  
    EnterCriticalSection();  
    if(/* error happens */)  
        return;  
    LeaveCriticalSection();  
}  

void data_process()
{
    EnterCriticalSection();
    if(/* error happens */)
        return;
    LeaveCriticalSection();

}    (2)单线程重复申请锁
void sub_func()  
{  
    EnterCriticalSection();  
    do_something();  
    LeaveCriticalSection();  
}  
  
void data_process()  
{  
    EnterCriticalSection();  
    sub_func();  
    LeaveCriticalSection();  
}  

void sub_func()
{
    EnterCriticalSection();
    do_something();
    LeaveCriticalSection();
}

void data_process()
{
    EnterCriticalSection();
    sub_func();
    LeaveCriticalSection();
}   

(3)双线程多锁申请
void data_process1()  
{  
    EnterCriticalSection(&cs1);  
    EnterCriticalSection(&cs2);  
    do_something1();  
    LeaveCriticalSection(&cs2);  
    LeaveCriticalSection(&cs1);  
}  
  
void data_process2()  
{  
    EnterCriticalSection(&cs2);  
    EnterCriticalSection(&cs1);  
    do_something2();  
    LeaveCriticalSection(&cs1);  
    LeaveCriticalSection(&cs2);  
}  

void data_process1()
{
    EnterCriticalSection(&cs1);
    EnterCriticalSection(&cs2);
    do_something1();
    LeaveCriticalSection(&cs2);
    LeaveCriticalSection(&cs1);
}

void data_process2()
{
    EnterCriticalSection(&cs2);
    EnterCriticalSection(&cs1);
    do_something2();
    LeaveCriticalSection(&cs1);
    LeaveCriticalSection(&cs2);
}   

(4)环形锁申请
/*
*             A   -  B
*             |      |
*             C   -  D
*/  

    假设有A、B、C、D四个人在一起吃饭,每个人左右各有一只筷子。所以,这其中要是有一个人想吃饭,他必须首先拿起左边的筷子,再拿起右边的筷子。现在,我们让所有的人同时开始吃饭。那么就很有可能出现这种情况。每个人都拿起了左边的筷子,或者每个人都拿起了右边的筷子,为了吃饭,他们现在都在等另外一只筷子。此时每个人都想吃饭,同时每个人都不想放弃自己已经得到的一那只筷子。所以,事实上大家都吃不了饭。

评分

参与人数 1技术分 +1 收起 理由
张熙韬 + 1

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马