java 原子变量_Java并发编程之原子变量

原子变量比锁的粒度更细,量级更轻,并且对于在多处理器系统上实现高性能的并发代码来说是非常关键的。

原子变量类相当于一种泛化的 volatile 变量,能够支持原子的和有条件的读-改-写操作。

原子类在内部使用现代 CPU 支持的 CAS 指令来实现同步。这些指令通常比锁更快。

原子更新基本类型AtomicBoolean - 原子更新布尔类型。

AtomicInteger - 原子更新整型。

AtomicLong - 原子更新长整型。

示例:

public class AtomicIntegerDemo {

public static void main(String[] args) throws InterruptedException {

ExecutorService executorService = Executors.newFixedThreadPool(5);

AtomicInteger count = new AtomicInteger(0);

for (int i = 0; i < 1000; i++) {

executorService.submit((Runnable) () -> {

System.out.println(Thread.currentThread().getName() + " count=" + count.get());

count.incrementAndGet();

});

}

executorService.shutdown();

executorService.awaitTermination(30, TimeUnit.SECONDS);

System.out.println("Final Count is : " + count.get());

}

}

原子更新数组AtomicIntegerArray - 原子更新整型数组里的元素。

AtomicLongArray - 原子更新长整型数组里的元素。

AtomicReferenceArray - 原子更新引用类型数组的元素。

AtomicBooleanArray - 原子更新布尔类型数组的元素。

示例:

public class AtomicIntegerArrayDemo {

private static AtomicIntegerArray atomicIntegerArray = new AtomicIntegerArray(10);

public static void main(final String[] arguments) throws InterruptedException {

for (int i = 0; i < atomicIntegerArray.length(); i++) {

atomicIntegerArray.set(i, i);

}

Thread t1 = new Thread(new Increment());

Thread t2 = new Thread(new Compare());

t1.start();

t2.start();

t1.join();

t2.join();

System.out.println("Final Values: ");

for (int i = 0; i < atomicIntegerArray.length(); i++) {

System.out.print(atomicIntegerArray.get(i) + " ");

}

}

static class Increment implements Runnable {

public void run() {

for (int i = 0; i < atomicIntegerArray.length(); i++) {

int add = atomicIntegerArray.incrementAndGet(i);

System.out.println(Thread.currentThread().getName() + ", index " + i + ", value: " + add);

}

}

}

static class Compare implements Runnable {

public void run() {

for (int i = 0; i < atomicIntegerArray.length(); i++) {

boolean swapped = atomicIntegerArray.compareAndSet(i, 2, 3);

if (swapped) {

System.out.println(Thread.currentThread().getName() + ", index " + i + ", value: 3");

}

}

}

}

}

原子更新引用类型AtomicReference - 原子更新引用类型。

AtomicReferenceFieldUpdater - 原子更新引用类型里的字段。

AtomicMarkableReference - 原子更新带有标记位的引用类型。可以原子更新一个布尔类型的标记位和应用类型。

public class AtomicReferenceDemo {

private static String message;

private static Person person;

private static AtomicReference aRmessage;

private static AtomicReference aRperson;

public static void main(String[] args) throws InterruptedException {

Thread t1 = new Thread(new MyRun1());

Thread t2 = new Thread(new MyRun2());

message = "hello";

person = new Person("Phillip", 23);

aRmessage = new AtomicReference(message);

aRperson = new AtomicReference(person);

System.out.println("Message is: " + message

+ "\nPerson is " + person.toString());

System.out.println("Atomic Reference of Message is: " + aRmessage.get()

+ "\nAtomic Reference of Person is " + aRperson.get().toString());

t1.start();

t2.start();

t1.join();

t2.join();

System.out.println("\nNow Message is: " + message

+ "\nPerson is " + person.toString());

System.out.println("Atomic Reference of Message is: " + aRmessage.get()

+ "\nAtomic Reference of Person is " + aRperson.get().toString());

}

static class MyRun1 implements Runnable {

public void run() {

aRmessage.compareAndSet(message, "Thread 1");

message = message.concat("-Thread 1!");

person.setAge(person.getAge() + 1);

person.setName("Thread 1");

aRperson.getAndSet(new Person("Thread 1", 1));

System.out.println("\n" + Thread.currentThread().getName() + " Values "

+ message + " - " + person.toString());

System.out.println("\n" + Thread.currentThread().getName() + " Atomic References "

+ message + " - " + person.toString());

}

}

static class MyRun2 implements Runnable {

public void run() {

message = message.concat("-Thread 2");

person.setAge(person.getAge() + 2);

person.setName("Thread 2");

aRmessage.lazySet("Thread 2");

aRperson.set(new Person("Thread 2", 2));

System.out.println("\n" + Thread.currentThread().getName() + " Values: "

+ message + " - " + person.toString());

System.out.println("\n" + Thread.currentThread().getName() + " Atomic References: "

+ aRmessage.get() + " - " + aRperson.get().toString());

}

}

static class Person {

private String name;

private int age;

Person(String name, int age) {

this.name = name;

this.age = age;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

int getAge() {

return age;

}

void setAge(int age) {

this.age = age;

}

@Override

public String toString() {

return "[name " + this.name + ", age " + this.age + "]";

}

}

}

原子更新字段类AtomicIntegerFieldUpdater - 原子更新整型的字段的更新器。

AtomicLongFieldUpdater - 原子更新长整型字段的更新器。

AtomicStampedReference - 原子更新带有版本号的引用类型。该类将整型数值与引用关联起来,可用于原子的更新数据和数据的版本号,可以解决使用 CAS 进行原子更新时可能出现的 ABA 问题。

public class AtomicStampedReferenceDemo {

private final static String INIT_REF = "abc";

public static void main(String[] args) throws InterruptedException {

AtomicStampedReference asr = new AtomicStampedReference<>(INIT_REF, 0);

System.out.println("初始对象为:" + asr.getReference());

final int stamp = asr.getStamp();

ExecutorService executorService = Executors.newFixedThreadPool(100);

for (int i = 0; i < 100; i++) {

executorService.submit(() -> {

try {

Thread.sleep(Math.abs((int) (Math.random() * 100)));

} catch (InterruptedException e) {

e.printStackTrace();

}

if (asr.compareAndSet(INIT_REF, Thread.currentThread().getName(), stamp, stamp + 1)) {

System.out.println(Thread.currentThread().getName() + " 修改了对象!");

System.out.println("新的对象为:" + asr.getReference());

}

});

}

executorService.shutdown();

executorService.awaitTermination(60, TimeUnit.SECONDS);

}

}免费Java资料需要自己领取,涵盖了Java、Redis、MongoDB、MySQL、Zookeeper、Spring Cloud、Dubbo高并发分布式等教程,一共30G。

传送门:https://mp.weixin.qq.com/s/JzddfH-7yNudmkjT0IRL8Q

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值