Synchronized关键字--总结于《Java多线程编程核心技术》

    由于代码过于分散,此篇博客就没有把代码贴出来,作为新年的第一篇博客,工作过于忙碌,没有时间看书和总结了,希望在新的2016年,能够继续深入了解Java。加油,可能是个最差的程序员。这是一篇未完结的博客,下次再补上。

1、方法内部的变量为线程安全
    “非线程安全”问题存在于“实例变量”中,如果是方法内部的私有变量,则不存在“非线程安全”问题。这是方法内部的变量是私有的特性造成的

2、实例变量是非线程安全的
    如果多个线程共同访问一个对象中得实例变量,则有可能造成“非线程安全”问题。

3、多个对象多个锁
    锁的概念是针对对象的,每一个对象都会有锁(lock)关键字synchronized取得的锁都是对象锁,而不是把一段方法或者代码当做锁,哪个线程先执行带synchronized关键字的方法,哪个线程就持有该方法所属对象的锁(lock),那么其他线程都必须处在等待状态。
多个线程访问多个对象,则JVM会创建多个锁。

4、synchronized方法与锁对象
    调用关键字synchronized声明的方法一定是排队运行的,只有共享资源的读写访问才需要同步,如果不是共享资源,那么根本没有同步的必要,多个方法被synchronized关键字修饰,多个线程调用这些方法也必须排队执行。
    A线程先持有object对象的lock锁,B线程可以以异步的方式调用object对象中得非synchronized类型的方法
    A线程先持有object对象的lock锁,B线程如果在这时需要调用object对象中得synchronized类型的方法则需要等待,也就是同步

5、synchronized 锁重入
    关键字synchronized拥有锁重入功能,也就是在使用synchronized时,当一个线程得到一个对象锁后,再次请求改对象锁时是可以再次得到该对象的锁的,简而言之,synchronized 方法/代码块内部调用奔雷的其他的synchronized方法/代码块,是永远可以得到锁的。此设计的基础是避免死锁,即有synchronized方法MethodA,在MethodA中调用了synchronized方法MethodB,是可以直接获取该锁的。而且在继承关系中,子类完全可以通过“可重入锁”调用父类的同步方法

6、出现异常,锁自动释放

7、同步不具备继承性
    父类有synchronized方法SuperMethod(),子类重写父类该方法,未申明为synchronized的方法,子类的该方法并不具有synchronized属性,因为同步不具备继承性

8、synchronized方法的弊端
    当线程持有某对象的锁的情况下,该方法需要做耗时操作的时候,别的线程需要长期等待,造成效率地下的问题。此处可以引入synchronized的代码块,通常可将赋值操作用synchronized(this)同步该赋值代码块,而耗时操作中保持异步执行,这样子的做法即保证了代码的异步高效,同时能够确保赋值操作的同步性,不会造成脏读。

9、synchronized代码块之间的同步性
    在使用synchronized(this)代码块的时候需要注意的是:当一个线程访问object的synchronized(this)同步代码块时,其他线程对同一个object中所有其他的synchron(this)同步代码快的方法将被阻塞。

10、synchronized(this)代码块是锁定当前对象的
    和synchronized方法一样,synchronized(this)代码块也是锁定当前对象的,也就是说持有的锁为当前对象的锁,线程A在调用ObjectA的sychronized(this)代码块时,线程B是无法调用ObjectA的synchronized方法的

11、将任意对象作为对象监视器
    synchronized(非this对象)格式的作用只有一个种:synchronized(非this对象)同步代码块。在多个线程持有”线程监视器”为同一个对象的前提下,同一时间只有一个线程可以执行synchronized(非this对象)同步代码块中得代码,当持有”对象监视器”为同一个对象的前提下,同一时间只有一个线程可以执行synchronized(非this对象)同步代码块中得代码
    synchronized(非this对象)的优点:如果一个类中有很多synchronized方法,这时虽然能够实现方法同步,但会收到阻塞,所以会影响运行效率,但如果使用synchronized(非this对象),此时该代码块与synchronized方法是异步的,不与其他锁this同步方法争抢this锁,可以大大提高运行效率。显然,synchronized中的对象必须是同一个对象,否则他们持有的锁就不是同一个锁了,所以就会造成异步。

12、静态同步synchronized方法与synchronized(class)代码块
    关键字synchronized还可以应用在static静态方法中,如果这样子写,那是对当前的.java文件对应的Class类进行持锁,给Class类加锁。而在非static方法中是对对象加锁。同步synchronized(class)代码块的作用其实和synchronized static方法的作用是一样的。

13、不要使用synchronized(String)此类锁,。
    因为在JVM中有一个String池的概念,容易导致持有相同对象的锁,以至于造成死锁。Java线程死锁是一个经典的多线程问题,因为不同的线程都在等候根本不可能被释放的锁,从而导致所有的任务都无法继续完成,在多线程技术中,“死锁”是必须避免的,因为这会造成线程的“假死”。早成死锁的一个例子

public class DealThread implements Runnale
{
    public String username;

    public Object lock1 = new Object();

    public Object lock2 = new Object();

    public void setFlag(String username)
    {
        this.username = username;
    }

    @Override
    public void run()
    {
        if(“a”.equals(username))
        {//持有lock1等待lock2
            synchronized(lock1)
            {
                try
                {
                    System.out.print(“username = “ + username);
                    Thread.sleep(3000);
                }
                catch(InterruptException e)
                {
                    e.printStackTrace();
                }

                synchronized(lock2)
                {
                    System.out.print(“按lock1 -> lock2 代码顺序执行“);
                }
            }
        }   

        if(“b”.equals(username))
        {//持有lock2等待lock1
            synchronized(lock2)
            {
                try
                {
                    System.out.print(“username = “ + username);
                    Thread.sleep(3000);
                }
                catch(InterruptException e)
                {
                    e.printStackTrace();
                }

                synchronized(lock1)
                {
                    System.out.print(“按lock2 -> lock1 代码顺序执行“);
                }
            }
        }   
    }
}

死锁是程序设计的bug,在设计程序的时候就要避免双方相互持有对方的锁的情况。只要互相等待对方释放的锁就有可能造成死锁。

13、锁对象的改变
  在将任何数据类型作为同步锁时,需要注意的是,是否有多个线程同时持有锁对象,如果同时持有相同的锁对象,则这些线程之间就是同步的,如果分别获得锁对象,这些线程之间就是异步的。持有锁的过程中,可以改变锁对象,改变锁对象的时候,原来那个锁被释放。只要锁对象不变,即使对象的属性改变,运行的结果还是同步的。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值