天天看點

java atomic使用_Java java.util.concurrent.atomic.AtomicReference的用法以及案例

1、AtomicReference用以支援對象的原子操作:AtomicReference 可以封裝引用一個V執行個體。

2、public final boolean compareAndSet(V expect, V update) ,可以支援并發通路,set的時候進行對比判斷,如果目前值和操作之前一樣則傳回false,否則表示資料沒有變化。

執行個體代碼:package com.what21;

import java.util.concurrent.CountDownLatch;

import java.util.concurrent.atomic.AtomicReference;

public class AtomicReferenceMain {

private static AtomicReference ar = new AtomicReference(0);

public static void test() throws InterruptedException {

int t = 100;

final int c = 100;

final CountDownLatch latch = new CountDownLatch(t);

for (int i = 0; i 

new Thread(new Runnable() {

@Override

public void run() {

for (int i = 0; i 

while (true) {

Integer temp = ar.get();

System.out.println("temp=" + temp);

if (ar.compareAndSet(temp, temp + 1)) {

break;

}

}

}

latch.countDown();

}

}).start();

}

latch.await();

System.out.println(ar.get());

}

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

test();

}

}

執行個體代碼,原子量實作的計數器:package com.what21;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

import java.util.concurrent.atomic.AtomicInteger;

public class AtomicCounter {

private AtomicInteger value = new AtomicInteger();

public int getValue() {

return value.get();

}

public int increase() {

return value.incrementAndGet();// 内部使用死循環for(;;)調用compareAndSet(current, next)

// return value.getAndIncrement();

}

public int increase(int i) {

return value.addAndGet(i);// 内部使用死循環for(;;)調用compareAndSet(current, next)

// return value.getAndAdd(i);

}

public int decrease() {

return value.decrementAndGet();// 内部使用死循環for(;;)調用compareAndSet(current, next)

// return value.getAndDecrement();

}

public int decrease(int i) {

return value.addAndGet(-i);// 内部使用死循環for(;;)調用compareAndSet(current, next)

// return value.addAndGet(-i);

}

public static void main(String[] args) {

final AtomicCounter counter = new AtomicCounter();

ExecutorService service = Executors.newCachedThreadPool();

for (int i = 0; i 

service.execute(new Runnable() {

@Override

public void run() {

System.out.println(counter.increase());

}

});

}

service.shutdown();

}

}

執行個體代碼,原子量實作的銀行取款:package com.what21;

import java.util.Random;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

import java.util.concurrent.atomic.AtomicLong;

public class AtomicAccount {

private AtomicLong balance;

public AtomicAccount(long money) {

balance = new AtomicLong(money);

System.out.println("Total Money:" + balance);

}

public void deposit(long money) {

balance.addAndGet(money);

}

public void withdraw(long money) {

for (; ; ) {//保證即時同一時間有人也在取款也可以再次嘗試取款,如果不需要并發嘗試取款,可以去掉這句

long oldValue = balance.get();

if (oldValue 

System.out.println(Thread.currentThread().getName() + " 餘額不足! 餘額:" + balance);

break;

}

try {Thread.sleep(new Random().nextInt(1000));} catch (Exception e) { }// 模拟取款時間

if (balance.compareAndSet(oldValue, oldValue - money)) {

System.out.println(Thread.currentThread().getName() + " 取款 " + money + " 成功! 餘額:" + balance);

break;

}

System.out.println(Thread.currentThread().getName() + " 遇到并發,再次嘗試取款!");

}

}

public static void main(String[] args) {

final AtomicAccount account = new AtomicAccount(1000);

ExecutorService pool = Executors.newCachedThreadPool();

int i = 0;

while (i++ 

pool.execute(new Runnable() {

@Override

public void run() {

account.withdraw(100);

}

});

}

pool.shutdown();

}

}