安卓同步锁使用小结
一、同步机制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的使用