IT虾米网

安卓同步锁的使用

luoye 2022年05月05日 手机开发 405 0

安卓同步锁使用小结

一、同步机制synchronized

作用

Synchronized是Java中解决并发问题的一种最常用最简单的方法 ,他可以确保线程互斥的访问同步代码
1、当多线程之间存在共享数据时候,synchronized可以保证同一时间只有一个线程执行锁定的代码块儿,防止线程交叉执行
2、 可见性
对于被synchronized修饰的代码块,如果A线程执行结束,会强制刷新线程缓存内容到内存,同时通知其它synchronized修饰的线程x的值无效,需要重新读取(这点跟volatile很相似),因此B线程在执行的时候也就能读到A线程对x的修改了,这就是synchronized的可见性。

应用方式

Java中每一个对象都可以作为锁,这是synchronized实现同步的基础:
1、普通同步方法(实例方法),锁是当前实例对象 ,进入同步代码前要获得当前实例的锁
2、静态同步方法,锁是当前类的class对象 ,进入同步代码前要获得当前类对象的锁
3、同步方法块,锁是括号里面的对象,对给定对象加锁,进入同步代码库前要获得给定对象的锁。
实例方法示例

  fun getInstance(): RequestUtils {
   
     
        if (mRequestUtils == null) {
   
     
            synchronized(RequestUtils::class) {
   
    //双重检验锁 
                if (mRequestUtils == null) {
   
     
                    mRequestUtils = RequestUtils() 
                    Log.i(Tag, "new RequestUtils()") 
                } 
            } 
        } 
        return mRequestUtils 
    } 

防止交叉执行使用示例
1、未加锁

class LockActivity : AppCompatActivity() {
   
     
    var index = "" 
    var str = 
        arrayOf("你", "好", "呀", "!") 
 
    override fun onCreate(savedInstanceState: Bundle?) {
   
     
        super.onCreate(savedInstanceState) 
        setContentView(R.layout.activity_lovk) 
        init_Listener() 
 
    } 
 
    fun init_Listener() {
   
     
        tv_click.setOnClickListener {
   
     
            val t1: Thread = MyThread() 
            val t2: Thread = MyThread() 
            t1.start() 
            t2.start() 
            Thread.sleep(500) 
 
        } 
    } 
    fun add(i: Int) {
   
     
        index = str[i] 
        Log.i("Lock==", index + Thread.currentThread().name) 
    } 
    inner class MyThread : Thread() {
   
     
        override fun run() {
   
     
            super.run() 
            for (i in 0..3) {
   
     
                add(i) 
            } 
        } 
 
    } 
 
} 

返回结果:
你Thread-5
你Thread-4
好Thread-5
好Thread-4
呀Thread-5
呀Thread-4
!Thread-5
!Thread-4
2、加锁后

class LockActivity : AppCompatActivity() {
   
     
    var index = "" 
    var str = 
        arrayOf("你", "好", "呀", "!") 
 
    override fun onCreate(savedInstanceState: Bundle?) {
   
     
        super.onCreate(savedInstanceState) 
        setContentView(R.layout.activity_lovk) 
        init_Listener() 
 
    } 
 
    fun init_Listener() {
   
     
        tv_click.setOnClickListener {
   
     
            val t1: Thread = MyThread() 
            val t2: Thread = MyThread() 
            t1.start() 
            t2.start() 
            Thread.sleep(500) 
//            Log.i("Lock==", index.toString()) 
        } 
    } 
 
    @Synchronized//加锁 
    fun add(i: Int) {
   
     
        index = str[i] 
        Log.i("Lock==", index + Thread.currentThread().name) 
    } 
 
    inner class MyThread : Thread() {
   
     
        override fun run() {
   
     
            super.run() 
            for (i in 0..3) {
   
     
                add(i) 
            } 
        } 
 
    } 
 
} 

返回结果:
你Thread-5
好Thread-5
呀Thread-5
!Thread-5
你Thread-4
好Thread-4
呀Thread-4
!Thread-4

二、Lock

使用示例

    Lock locka = new ReentrantLock(); 
           try {
   
     
                    Thread.sleep(5000); 
                    locka.lock(); 
                    if (mRTASRTest == null) {
   
     
                        Params.isNeedWhile = true; 
                        mRTASRTest = RTASRTest.mainA(); 
                        Thread.sleep(2000); 
                        mRTASRTest.sendMess(raf); 
                        Log.i("RTASRTest", "mainA"); 
                    } 
                    locka.unlock(); 
                } catch (Exception e) {
   
     
                    e.printStackTrace(); 
                } 

创建对象后使用lock.lock()方法进行加锁,注意:这个lock必须要进行unlock()的操作。如果不进行手动释放这锁会一直存在引用,会造成很多意想不到的问题。比如可能频繁GC,严重就会ANR。

参考文献

【Java并发编程之深入理解】Synchronized的使用


评论关闭
IT虾米网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!

安卓单例使用