安卓同步锁的使用

安卓同步锁使用小结

一、同步机制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的使用

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Android Studio中,线程是一种同步机制,用于确保多个线程之间的互斥访问。在多线程编程中,如果多个线程同时访问共享资源,可能会导致数据不一致或竞争条件的问题。线程可以用来解决这些问题。 Android Studio中常用的线程有以下几种: 1. synchronized关键字:synchronized关键字可以应用于方法或代码块,用于保护临界区,确保同一时间只有一个线程可以执行该方法或代码块。当某个线程进入synchronized方法或代码块时,其他线程需要等待。 例如: ```java synchronized void method() { // 临界区 } ``` 2. ReentrantLock类:ReentrantLock是一个可重入,提供了与synchronized相似的功能,并且更加灵活。与synchronized相比,ReentrantLock提供了更多的功能,如可定时的、可轮询的、公平的和可中断的等待。 例如: ```java ReentrantLock lock = new ReentrantLock(); lock.lock(); // 获取 try { // 临界区 } finally { lock.unlock(); // 释放 } ``` 3. Condition接口:Condition接口是与ReentrantLock类一起使用的,用于实现线程间的协调与通信。可以通过Condition的await()方法使线程等待,通过signal()方法唤醒等待的线程。 例如: ```java ReentrantLock lock = new ReentrantLock(); Condition condition = lock.newCondition(); lock.lock(); try { while (conditionIsFalse) { condition.await(); // 线程等待 } // 临界区 } finally { lock.unlock(); } // 在某个地方唤醒等待的线程 lock.lock(); try { condition.signal(); // 唤醒等待的线程 } finally { lock.unlock(); } ``` 这些是在Android Studio中使用的一些常见线程机制。根据具体的需求和场景,选择适合的线程可以提高多线程程序的稳定性和性能。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值