Synchronized全面详解

版权声明:如需转载,请标明转载出处哦! https://blog.csdn.net/Z0157/article/details/81464054

线程安全的概念:
    当多个线程访问同一个类(对象或方法)的时候,该类始终能表现出正确的行为,
    那么这个类(对象或者方法)就是线程安全的。
Synchronized:
一、多个线程一个锁:
    1、按照cpu分配的先后顺序排队访问
    2、不断尝试获得锁,
    3、如果拿到锁执行代码块里的内容,如果拿不到继续尝试获得锁
    4、存在锁竞争的问题

二、多个线程多个锁:
    关键字 synchronized获得的锁都是对象锁,而不是把一段代码或方法当成锁,
    static synchronized methodname(){}:
    该方法是锁住一个.class类,独占锁,多线程环境下,不同的对象访问,要竞争该锁,排队执行;

    synchronized methodname(){}:
    锁住的是持有该方法所属的对象的锁(Lock),不同线程上不同的对象访问该方法互不影响,
    多个(eg:2)对象,线程获得的就是多个(2)不同的锁;
    是该方法所在类 new 的一个对象上的一个锁,同一个对象访问该方法多次按照先后顺序排队;
    
asynchronized:
    异步:不加synchronized,修饰方法的时候,不需要释放该对象上的锁,该对象就可以直接调用该方法;

    
同步锁的目的就是为了线程安全,其实线程安全来说,需要满足2个特性:
1、原子性
2、可见性
    
脏读;
    对同一个对象方法加锁的时候,要考虑到业务整体性,get和set要同时加synchronized,保证业务的原子性
    不然出现脏数据;
    
synchronized 拥有锁重入功能:
    当一个线程得到一个对象锁之后,再次请求此对象时候是可以再次得到该对象的锁,出现异常锁自动释放;

注意:
1、尽量不要用锁代码块去代替锁方法,减少锁的粒度;
2、不要使用String的常量加锁,会出现死循环;当使用一个对象加锁,如果该对象本身发生改变,那么持有的锁
    就不同,如果对象本身不发生改变,那么依然是同步,几十是对象的熟悉发生改变;
3、死锁问题:
    死锁是这样一种情形:多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放。
    由于线程被无限期地阻塞,因此程序不可能正常终止。
    java 死锁产生的四个必要条件:
    1、互斥使用,即当资源被一个线程使用(占有)时,别的线程不能使用
    2、不可抢占,资源请求者不能强制从资源占有者手中夺取资源,资源只能由资源占有者主动释放。
    3、请求和保持,即当资源请求者在请求其他的资源的同时保持对原有资源的占有。 
    4、循环等待,即存在一个等待队列:P1占有P2的资源,P2占有P3的资源,P3占有P1的资源。
    这样就形成了一个等待环路
    
当上述四个条件都成立的时候,便形成死锁。当然,死锁的情况下如果打破上述任何一个条件,便可让死锁消失。

解决死锁问题的方法是:一种是用synchronized,一种是用Lock显式锁实现。

时间不早了,睡觉。。。。

    

    
    

    

    
    

猜你喜欢

转载自blog.csdn.net/Z0157/article/details/81464054