object two_原子操作_getUniqueId extends App {
private val uid = new AtomicLong(0L) //定义了一个Long类型的原子变量
def getUniqueId: Long = uid.incrementAndGet() //使用了该变量的原子操作:incrementAndGet;它会读取uid然后计算+1的值,之后将结果写会变量uid中,并返回这个结果。
execute(println(s"Uid asynchronously : $getUniqueId")) // 创建个全局对象线程池
println(s"Got a unique id : $getUniqueId") //main线程也执行一次getUniqueId方法
Thread.sleep(1000)
}
compareAndSet使用了源码中的compareAndSwapLong(valueOffset,oldValue,newValue) valueOffset表示的是原子变量uid的值在内存中如果发生了变化,发生变化后新值所在的地址,如果oldValue的值 == valueoffSet的值,那么就将newValue赋值给ValueOffset然后地址发生偏移,此时uid的值就是newValue,返回的是一个true如果oldValue != valueOffset那么返回的就是一个false
object 重写_incrementAndGet extends App {
private val uid: AtomicLong = new AtomicLong(0L) //定义了一个Long类型的原子变量
@tailrec def 重写_incrementAndGet: Long = {
val oldUid = uid.get()
val newUid = oldUid + 1
if (uid.compareAndSet(oldUid, newUid)) newUid else 重写_incrementAndGet
}
for (i <- 1 to 12) execute(println(s"ThreadName = ${Thread.currentThread().getName};Uid asynchronously : $重写_incrementAndGet")) // 创建个全局对象线程池
println(s"Got a unique id : $重写_incrementAndGet") //main线程也执行一次getUniqueId方法
Thread.sleep(1000)
}
因为执行无锁操作的线程不会尝试获取任何锁;
(本文章虽然采用的代码为scala代码,但java代码与Scala代码可以互相转换,且本质上两者所阐述的东西都是一致的)