////////////FIRST METHOD USING SINGLE boolean//////////////
public class ThreadTest implements Runnable {
ThreadTest() {
Log.i("Ayaz", "Constructor..");
}
private boolean lockBoolean = false;
public void run() {
Log.i("Ayaz", "Thread started.." + Thread.currentThread().getName());
while (lockBoolean) {
// infinite loop for other thread if one is accessing
}
lockBoolean = true;
synchronizedMethod();
}
/**
* This method is synchronized without using synchronized keyword
*/
public void synchronizedMethod() {
Log.e("Ayaz", "processing...." + Thread.currentThread().getName());
try {
Thread.currentThread().sleep(3000);
} catch (Exception e) {
System.out.println("Exp");
}
Log.e("Ayaz", "complete.." + Thread.currentThread().getName());
lockBoolean = false;
}
} //end of ThreadTest class
//For testing use below line in main method or in Activity
ThreadTest threadTest = new ThreadTest();
Thread threadA = new Thread(threadTest, "A thead");
Thread threadB = new Thread(threadTest, "B thead");
threadA.start();
threadB.start();
///////////SECOND METHOD USING TWO boolean/////////////////
public class ThreadTest implements Runnable {
ThreadTest() {
Log.i("Ayaz", "Constructor..");
}
private boolean isAnyThreadInUse = false;
private boolean lockBoolean = false;
public void run() {
Log.i("Ayaz", "Thread started.." + Thread.currentThread().getName());
while (!lockBoolean)
if (!isAnyThreadInUse) {
isAnyThreadInUse = true;
synchronizedMethod();
lockBoolean = true;
}
}
/**
* This method is synchronized without using synchronized keyword
*/
public void synchronizedMethod() {
Log.e("Ayaz", "processing...." + Thread.currentThread().getName());
try {
Thread.currentThread().sleep(3000);
} catch (Exception e) {
System.out.println("Exp");
}
Log.e("Ayaz", "complete.." + Thread.currentThread().getName());
isAnyThreadInUse = false;
}
} // end of ThreadTest class
//For testing use below line in main method or in Activity
ThreadTest threadTest = new ThreadTest();
Thread t1 = new Thread(threadTest, "a thead");
Thread t2 = new Thread(threadTest, "b thead");
t1.start();
t2.start();
# 1 楼答案
有很多方法可以做到这一点,但每种方法都包含很多味道。Java8还附带了新的并发特性。 确保线程安全的一些方法有:
Semaphores
锁-
Reentrantlock,ReadWriteLock,StampedLock
(Java 8)# 2 楼答案
只有局部方法的变量/引用。或者确保任何实例变量都是不可变的
# 3 楼答案
# 4 楼答案
您可以通过使所有数据不可变来确保代码的线程安全,如果没有可变性,那么一切都是线程安全的
第二,您可能想看看java并发API,它提供了读/写锁,在读写器很多的情况下性能更好。纯同步关键字也会阻止两个读卡器
# 5 楼答案
实际上,有很多方法:
synchronized
块和方法时访问的锁相同的功能,它甚至更强大李># 6 楼答案
为了保持可预测性,您必须确保对可变数据的所有访问都是按顺序进行的,或者处理并行访问引起的问题
最严重的保护使用
synchronized
关键字。除此之外,至少还有两层可能性,每层都有各自的好处锁/信号灯
这些方法非常有效。例如,如果一个结构被多个线程读取,但只被一个线程更新,那么
ReadWriteLock
可能会很有用如果选择与算法匹配的锁,锁的效率会更高
原子
例如,使用
AtomicReference
通常可以提供完全无锁的功能。这通常会带来巨大的好处原子学背后的理由是允许它们失败,但告诉你它们失败的方式是你可以处理的
例如,如果要更改某个值,可以读取该值,然后写入其新值,只要该值仍然是旧值。这被称为“比较和设置”或
cas
,通常可以在硬件中实现,因此非常有效。你所需要的就是:然而,请注意,可预测性并不总是必需的