线程共享和协作(二):Synchronized、ThreadLocal、Volatile如何实现线程共享

AtomicInteger a1 = new AtomicInteger(10);

// 带有时间戳的原子类,不存在ABA问题,第二个参数就是默认时间戳,这里指定为0

AtomicStampedReference a2 = new AtomicStampedReference(10, 0);

public static void main(String[] args) {

ABA a = new ABA();

a.test();

}

public void test() {

new Thread1().start();

new Thread2().start();

new Thread3().start();

new Thread4().start();

}

class Thread1 extends Thread {

@Override

public void run() {

a1.compareAndSet(10, 11);

a1.compareAndSet(11, 10);

}

}

class Thread2 extends Thread {

@Override

public void run() {

try {

Thread.sleep(200); // 睡0.2秒,给线程1时间做ABA操作

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println(“AtomicInteger原子操作:” + a1.compareAndSet(10, 11));

}

}

class Thread3 extends Thread {

@Override

public void run() {

try {

Thread.sleep(500); // 睡0.5秒,保证线程4先执行

} catch (InterruptedException e) {

e.printStackTrace();

}

int stamp = a2.getStamp();

a2.compareAndSet(10, 11, stamp, stamp + 1);

stamp = a2.getStamp();

a2.compareAndSet(11, 10, stamp, stamp + 1);

}

}

class Thread4 extends Thread {

@Override

public void run() {

int stamp = a2.getStamp();

try {

Thread.sleep(1000); // 睡一秒,给线程3时间做ABA操作

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println(“AtomicStampedReference原子操作:” + a2.compareAndSet(10, 11, stamp, stamp + 1));

}

}

}

Volatile

作用

Volatile可以看做是一个轻量级的synchronized,它可以在多线程并发的情况下保证变量的“可见性”,

什么是可见性

就是在一个线程的工作内存中修改了该变量的值,该变量的值立即能回显到主内存中,从而保证所有的线程看到这个变量的值是一致的,其二 volatile 禁止了指令重排,所以在处理同步问题上它大显作用,而且它的开销比synchronized小、使用成本更低。

虽然 volatile 变量具有可见性和禁止指令重排序,但是并不能说 volatile 变量能确保并发安全。

举个栗子:在写单例模式中,除了用静态内部类外,还有一种写法也非常受欢迎,就是Volatile+DCL:

public class Singleton {

private static volatile Singleton instance;

private Singleton() {

}

public static Singleton getInstance() {

if (instance == null) {

synchronized (Singleton.class) {

if (instance == null)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值