public class A{
private B b = null;
public B get(){
if(b == null) // thread1,thread2 同时判断为null
b = new B();
return b ;
}
}
2.3 复合操作
避免竞态条件问题,就要a线程在修改变量时,b线程已经执行完,或者不执行。
对同一个状态有A B 操作,一个线程执行A操作,另一个线程执行B操作,要么是已经执行完,要不就是完全不执行,A B操作都是原子操作。
++count 是复合操作,要以线程安全的方式去修复执行。
使用线程安全的对象进行记录
public class A{
private final AtomicLong count = new AtomicLong(0);
public long getCount(return count.get());
public void set(){
count.incrementAndGet();
}
}
3.加锁机制
3.1 内置锁(同步代码块 synchronized)
同步代码块
synchronized(lock){
//访问或修改由锁保护的共享状态
}
某个线程可以重如自己持有的锁的代码中,每个锁有一个计数器,所有者线程,计数器值=0
,锁未被持有,线程请求未被持有的锁,jvm记下锁持有者,计数器值+1, 同一个线程再次获得锁,计数值+1,线程退出,则-1.
public class A{
public synchronized void do{
...
}
}
public class B extends A{
public synchronized void do{
super.do(); //同一个对象,可以多次重入加锁的代码。
}
}