Android基础知识

Synchronized的四大用法和区别

2019-06-02  本文已影响25人  Magic旭

Synchronized(同步锁)

本来想用单元测试写case的,但是发现单元测试不支持Sleep操作,无奈下只能回到App上运行打log输出了。让我们回到正题,探讨常用的Synchronized四大用法。

Synchronized四大用法(Java与Kotlin版本)

  1. synchronized修饰普通方法,Kotlin对应的是@Synchronized注解类。
  2. synchronized修饰静态方法,Kotlin对应的是@Synchronized注解类。
  3. synchronized(this),Kotlin对应的是synchronized(this)
  4. synchronized(xxx.class),Kotlin对应的是synchronized(xxx::class.java)。

注意:以下都是Kotlin代码,只需要执行test方法,就能得到对应输出结果。

Synchronized修饰普通方法作用与含义
//
class TestLock {
   fun test(){
        val mLock = LockTest()
        //如果是不同变量,那就是异步执行了
//      val mLock2 = LockTest()
        val mThreadA = ThreadA()
        mThreadA.myLock = mLock
        val mThreadB = ThreadB()
        mThreadB.myLock = mLock
//        mThreadB.myLock = mLock2

        mThreadA.start()
        mThreadB.start()
        MyLog.i("game is start")
    }

    class ThreadA: Thread() {
        var myLock:LockTest? = null
        override fun run() {
            myLock?.lockTest()
            MyLog.i("ThreadA is coming")
        }
    }

    class ThreadB: Thread(){
        var myLock:LockTest? = null
        override fun run() {
            myLock?.lockTest()
            MyLog.i("ThreadB is coming")
        }
    }


    class LockTest{
        //修饰普通方法
        @Synchronized fun lockTest(){
            MyLog.i("lock is Start")
            Thread.sleep(1000)
            MyLog.i("lock is End")
        }
    }
}

当然如果上面注解去掉,ThreadA和ThreadB持有不同的变量,那么 lockTest方法的调用就会异步执行。


image.png
Synchronized修饰静态方法作用与含义
class TestLock2 {
    fun test(){
        //类锁无论变量是否同一个,都同步执行
        val mLock = LockTest()
        val mLock2 = LockTest()
        val mThreadA = ThreadA()
        mThreadA.myLock = mLock
        val mThreadB = ThreadB()
//        mThreadB.myLock = mLock
        mThreadB.myLock = mLock2

        mThreadA.start()
        mThreadB.start()
        MyLog.i("game is start")
    }

    class ThreadA: Thread() {
        var myLock:LockTest? = null
        override fun run() {
            MyLog.i("ThreadA of Name:${Thread.currentThread().name} is coming")
            myLock?.notifyLockTest()
        }
    }

    class ThreadB: Thread(){
        var myLock:LockTest? = null
        override fun run() {
            MyLog.i("ThreadB of Name:${Thread.currentThread().name} is coming")
            myLock?.notifyLockTest()
        }
    }


    class LockTest{
        //修饰普通方法
        companion object {
            @Synchronized fun lockTest(){
                MyLog.i("currentName:${Thread.currentThread().name} lock is Start")
                Thread.sleep(1000)
                MyLog.i("currentName:${Thread.currentThread().name} lock is End")
            }
        }

        fun notifyLockTest(){
            lockTest()
        }
    }
}
Synchronized(this) 作用与含义

该作用与含义和Synchronized修饰普通方法是一模一样的,请直接看代码与结果。

class TestLock {
    fun test(){
        val mLock = LockTest()
        //如果是不同变量,那就是异步执行了
//        val mLock2 = LockTest()
        val mThreadA = ThreadA()
        mThreadA.myLock = mLock
        val mThreadB = ThreadB()
        mThreadB.myLock = mLock
//        mThreadB.myLock = mLock2

        mThreadA.start()
        mThreadB.start()
        MyLog.i("game is start")
    }

    class ThreadA: Thread() {
        var myLock:LockTest? = null
        override fun run() {
            myLock?.lockTest()
            MyLog.i("ThreadA of Name:${Thread.currentThread().name} is coming")
        }
    }

    class ThreadB: Thread(){
        var myLock:LockTest? = null
        override fun run() {
            myLock?.lockTest()
            MyLog.i("ThreadB of Name:${Thread.currentThread().name} is coming")
        }
    }


    class LockTest{
        //修饰普通方法
        @Synchronized fun lockTest(){
            synchronized(this){
                MyLog.i("currentName:${Thread.currentThread().name} lock is Start")
                Thread.sleep(1000)
                MyLog.i("currentName:${Thread.currentThread().name} lock is End")
            }
        }
    }
}

不同变量时候,ThreadA和ThreadB是异步执行的。


image.png
Synchronized(xxxx.class) 作用与含义

该作用与含义和Synchronized修饰静态方法是一模一样的,请直接看代码与结果。

class TestLock2 {
    fun test(){
        //类锁无论变量是否同一个,都同步执行
        val mLock = LockTest()
        val mLock2 = LockTest()
        val mThreadA = ThreadA()
        mThreadA.myLock = mLock
        val mThreadB = ThreadB()
        mThreadB.myLock = mLock
//        mThreadB.myLock = mLock2

        mThreadA.start()
        mThreadB.start()
        MyLog.i("game is start")
    }

    class ThreadA: Thread() {
        var myLock:LockTest? = null
        override fun run() {
            MyLog.i("ThreadA of Name:${Thread.currentThread().name} is coming")
            myLock?.notifyLockTest()
        }
    }

    class ThreadB: Thread(){
        var myLock:LockTest? = null
        override fun run() {
            MyLog.i("ThreadB of Name:${Thread.currentThread().name} is coming")
            myLock?.notifyLockTest()
        }
    }


    class LockTest{
        //修饰普通方法
        companion object {
            fun lockTest(){
                MyLog.i("currentName:${Thread.currentThread().name} lock is Start")
                Thread.sleep(1000)
                MyLog.i("currentName:${Thread.currentThread().name} lock is End")
            }
        }

        fun notifyLockTest(){
            synchronized(TestLock2::class.java){
                lockTest()
            }
        }
    }
}

总结

  1. synchronized修饰普通方法与synchronized(this)可以简单理解为变量锁,他们只能针对同个变量达到同步执行效果;如果是不同变量就会异步执行。
  2. synchronized修饰静态方法与synchronized(xxx.class)可以简单理解为类锁,只要调用同个类的加锁方法,都能达到同步执行效果。
上一篇下一篇

猜你喜欢

热点阅读