本指南根据 Jakob Jenkov 最新博客翻译,请随时关注博客更新:http://tutorials.jenkov.com/java-util-concurrent/index.html。
本指南已做成中英文对照阅读版的 pdf 文档,有兴趣的朋友可以去 Java并发工具包java.util.concurrent用户指南中英文对照阅读版.pdf[带书签] 进行下载。
本文很大程度上还是个 "半成品",所以当你发现一些被漏掉的类或接口时,请耐心等待。在我空闲的时候会把它们加进来的。
抛异常 | 特定值 | 阻塞 | 超时 | |
---|---|---|---|---|
插入 | add(o) | offer(o) | put(o) | offer(o, timeout, timeunit) |
移除 | remove(o) | poll(o) | take(o) | poll(timeout, timeunit) |
检查 | element(o) | peek(o) |
01.
public
class
BlockingQueueExample {
02.
03.
public
static
void
main(String[] args)
throws
Exception {
04.
05.
BlockingQueue queue =
new
ArrayBlockingQueue(
1024
);
06.
07.
Producer producer =
new
Producer(queue);
08.
Consumer consumer =
new
Consumer(queue);
09.
10.
new
Thread(producer).start();
11.
new
Thread(consumer).start();
12.
13.
Thread.sleep(
4000
);
14.
}
15.
}
01.
public
class
Producer
implements
Runnable{
02.
03.
protected
BlockingQueue queue =
null
;
04.
05.
public
Producer(BlockingQueue queue) {
06.
this
.queue = queue;
07.
}
08.
09.
public
void
run() {
10.
try
{
11.
queue.put(
"1"
);
12.
Thread.sleep(
1000
);
13.
queue.put(
"2"
);
14.
Thread.sleep(
1000
);
15.
queue.put(
"3"
);
16.
}
catch
(InterruptedException e) {
17.
e.printStackTrace();
18.
}
19.
}
20.
}
01.
public
class
Consumer
implements
Runnable{
02.
03.
protected
BlockingQueue queue =
null
;
04.
05.
public
Consumer(BlockingQueue queue) {
06.
this
.queue = queue;
07.
}
08.
09.
public
void
run() {
10.
try
{
11.
System.out.println(queue.take());
12.
System.out.println(queue.take());
13.
System.out.println(queue.take());
14.
}
catch
(InterruptedException e) {
15.
e.printStackTrace();
16.
}
17.
}
18.
}
1.
BlockingQueue queue =
new
ArrayBlockingQueue(
1024
);
2.
3.
queue.put(
"1"
);
4.
5.
Object object = queue.take();
1.
BlockingQueue queue =
new
ArrayBlockingQueue(
1024
);
2.
3.
queue.put(
"1"
);
4.
5.
String string = queue.take();
1.
public
interface
Delayed
extends
Comparable
2.
3.
public
long
getDelay(TimeUnit timeUnit);
4.
5.
}
1.
DAYS
2.
HOURS
3.
MINUTES
4.
SECONDS
5.
MILLISECONDS
6.
MICROSECONDS
7.
NANOSECONDS
01.
public
class
DelayQueueExample {
02.
03.
public
static
void
main(String[] args) {
04.
DelayQueue queue =
new
DelayQueue();
05.
06.
Delayed element1 =
new
DelayedElement();
07.
08.
queue.put(element1);
09.
10.
Delayed element2 = queue.take();
11.
}
12.
}
DelayedElement 是我所创建的一个 DelayedElement 接口的实现类,它不在 java.util.concurrent 包里。你需要自行创建你自己的 Delayed 接口的实现以使用 DelayQueue 类。
1.
BlockingQueue unbounded =
new
LinkedBlockingQueue();
2.
BlockingQueue bounded =
new
LinkedBlockingQueue(
1024
);
3.
4.
bounded.put(
"Value"
);
5.
6.
String value = bounded.take();
1.
BlockingQueue queue =
new
PriorityBlockingQueue();
2.
3.
//String implements java.lang.Comparable
4.
queue.put(
"Value"
);
5.
6.
String value = queue.take();
据此,把这个类称作一个队列显然是夸大其词了。它更多像是一个汇合点。
抛异常 | 特定值 | 阻塞 | 超时 | |
---|---|---|---|---|
插入 | addFirst(o) | offerFirst(o) | putFirst(o) | offerFirst(o, timeout, timeunit) |
移除 | removeFirst(o) | pollFirst(o) | takeFirst(o) | pollFirst(timeout, timeunit) |
检查 | getFirst(o) | peekFirst(o) |
抛异常 | 特定值 | 阻塞 | 超时 | |
---|---|---|---|---|
插入 | addLast(o) | offerLast(o) | putLast(o) | offerLast(o, timeout, timeunit) |
移除 | removeLast(o) | pollLast(o) | takeLast(o) | pollLast(timeout, timeunit) |
检查 | getLast(o) | peekLast(o) |
BlockingQueue | BlockingDeque |
---|---|
add() | addLast() |
offer() x 2 | offerLast() x 2 |
put() | putLast() |
remove() | removeFirst() |
poll() x 2 | pollFirst() |
take() | takeFirst() |
element() | getFirst() |
peek() | peekFirst() |
1.
BlockingDeque deque =
new
LinkedBlockingDeque();
2.
3.
deque.addFirst(
"1"
);
4.
deque.addLast(
"2"
);
5.
6.
String two = deque.takeLast();
7.
String one = deque.takeFirst();
1.
BlockingDeque deque =
new
LinkedBlockingDeque();
2.
3.
deque.addFirst(
"1"
);
4.
deque.addLast(
"2"
);
5.
6.
String two = deque.takeLast();
7.
String one = deque.takeFirst();
1.
ConcurrentMap concurrentMap =
new
ConcurrentHashMap();
2.
3.
concurrentMap.put(
"key"
,
"value"
);
4.
5.
Object value = concurrentMap.get(
"key"
);
NavigableMap 中的方法不再赘述,本小节我们来看一下 ConcurrentNavigableMap 添加的方法。
1.
ConcurrentNavigableMap map =
new
ConcurrentSkipListMap();
2.
3.
map.put(
"1"
,
"one"
);
4.
map.put(
"2"
,
"two"
);
5.
map.put(
"3"
,
"three"
);
6.
7.
ConcurrentNavigableMap headMap = map.headMap(
"2"
);
1.
ConcurrentNavigableMap map =
new
ConcurrentSkipListMap();
2.
3.
map.put(
"1"
,
"one"
);
4.
map.put(
"2"
,
"two"
);
5.
map.put(
"3"
,
"three"
);
6.
7.
ConcurrentNavigableMap tailMap = map.tailMap(
"2"
);
1.
ConcurrentNavigableMap map =
new
ConcurrentSkipListMap();
2.
3.
map.put(
"1"
,
"one"
);
4.
map.put(
"2"
,
"two"
);
5.
map.put(
"3"
,
"three"
);
6.
7.
ConcurrentNavigableMap subMap = map.subMap(
"2"
,
"3"
);
关于这些方法更多信息参考官方 Java 文档。
01.
CountDownLatch latch =
new
CountDownLatch(
3
);
02.
03.
Waiter waiter =
new
Waiter(latch);
04.
Decrementer decrementer =
new
Decrementer(latch);
05.
06.
new
Thread(waiter) .start();
07.
new
Thread(decrementer).start();
08.
09.
Thread.sleep(
4000
);
10.
11.
public
class
Waiter
implements
Runnable{
12.
13.
CountDownLatch latch =
null
;
14.
15.
public
Waiter(CountDownLatch latch) {
16.
this
.latch = latch;
17.
}
18.
19.
public
void
run() {
20.
try
{
21.
latch.await();
22.
}
catch
(InterruptedException e) {
23.
e.printStackTrace();
24.
}
25.
26.
System.out.println(
"Waiter Released"
);
27.
}
28.
}
29.
30.
public
class
Decrementer
implements
Runnable {
31.
32.
CountDownLatch latch =
null
;
33.
34.
public
Decrementer(CountDownLatch latch) {
35.
this
.latch = latch;
36.
}
37.
38.
public
void
run() {
39.
40.
try
{
41.
Thread.sleep(
1000
);
42.
this
.latch.countDown();
43.
44.
Thread.sleep(
1000
);
45.
this
.latch.countDown();
46.
47.
Thread.sleep(
1000
);
48.
this
.latch.countDown();
49.
}
catch
(InterruptedException e) {
50.
e.printStackTrace();
51.
}
52.
}
53.
}
1.
CyclicBarrier barrier =
new
CyclicBarrier(
2
);
1.
barrier.await();
1.
barrier.await(
10
, TimeUnit.SECONDS);
1.
Runnable barrierAction = ... ;
2.
CyclicBarrier barrier =
new
CyclicBarrier(
2
, barrierAction);
01.
Runnable barrier1Action =
new
Runnable() {
02.
public
void
run() {
03.
System.out.println(
"BarrierAction 1 executed "
);
04.
}
05.
};
06.
Runnable barrier2Action =
new
Runnable() {
07.
public
void
run() {
08.
System.out.println(
"BarrierAction 2 executed "
);
09.
}
10.
};
11.
12.
CyclicBarrier barrier1 =
new
CyclicBarrier(
2
, barrier1Action);
13.
CyclicBarrier barrier2 =
new
CyclicBarrier(
2
, barrier2Action);
14.
15.
CyclicBarrierRunnable barrierRunnable1 =
16.
new
CyclicBarrierRunnable(barrier1, barrier2);
17.
18.
CyclicBarrierRunnable barrierRunnable2 =
19.
new
CyclicBarrierRunnable(barrier1, barrier2);
20.
21.
new
Thread(barrierRunnable1).start();
22.
new
Thread(barrierRunnable2).start();
01.
public
class
CyclicBarrierRunnable
implements
Runnable{
02.
03.
CyclicBarrier barrier1 =
null
;
04.
CyclicBarrier barrier2 =
null
;
05.
06.
public
CyclicBarrierRunnable(
07.
CyclicBarrier barrier1,
08.
CyclicBarrier barrier2) {
09.
10.
this
.barrier1 = barrier1;
11.
this
.barrier2 = barrier2;
12.
}
13.
14.
public
void
run() {
15.
try
{
16.
Thread.sleep(
1000
);
17.
System.out.println(Thread.currentThread().getName() +
18.
" waiting at barrier 1"
);
19.
this
.barrier1.await();
20.
21.
Thread.sleep(
1000
);
22.
System.out.println(Thread.currentThread().getName() +
23.
" waiting at barrier 2"
);
24.
this
.barrier2.await();
25.
26.
System.out.println(Thread.currentThread().getName() +
27.
" done!"
);
28.
29.
}
catch
(InterruptedException e) {
30.
e.printStackTrace();
31.
}
catch
(BrokenBarrierException e) {
32.
e.printStackTrace();
33.
}
34.
}
35.
}
Thread-1 done!
01.
Exchanger exchanger =
new
Exchanger();
02.
03.
ExchangerRunnable exchangerRunnable1 =
04.
new
ExchangerRunnable(exchanger,
"A"
);
05.
06.
ExchangerRunnable exchangerRunnable2 =
07.
new
ExchangerRunnable(exchanger,
"B"
);
08.
09.
new
Thread(exchangerRunnable1).start();
10.
new
Thread(exchangerRunnable2).start();
01.
public
class
ExchangerRunnable
implements
Runnable{
02.
03.
Exchanger exchanger =
null
;
04.
Object object =
null
;
05.
06.
public
ExchangerRunnable(Exchanger exchanger, Object object) {
07.
this
.exchanger = exchanger;
08.
this
.object = object;
09.
}
10.
11.
public
void
run() {
12.
try
{
13.
Object previous =
this
.object;
14.
15.
this
.object =
this
.exchanger.exchange(
this
.object);
16.
17.
System.out.println(
18.
Thread.currentThread().getName() +
19.
" exchanged "
+ previous +
" for "
+
this
.object
20.
);
21.
}
catch
(InterruptedException e) {
22.
e.printStackTrace();
23.
}
24.
}
25.
}
Thread-1 exchanged B for A
如果你将信号量用于保护一个重要部分,试图进入这一部分的代码通常会首先尝试获得一个许可,然后才能进入重要部分(代码块),执行完之后,再把许可释放掉。比如这样:
1.
Semaphore semaphore =
new
Semaphore(
1
);
2.
3.
//critical section
4.
semaphore.acquire();
5.
6.
...
7.
8.
semaphore.release();
1.
Semaphore semaphore =
new
Semaphore(
1
,
true
);
这些方法的细节请参考 Java 文档。
01.
ExecutorService executorService = Executors.newFixedThreadPool(
10
);
02.
03.
executorService.execute(
new
Runnable() {
04.
public
void
run() {
05.
System.out.println(
"Asynchronous task"
);
06.
}
07.
});
08.
09.
executorService.shutdown();
1.
ExecutorService executorService1 = Executors.newSingleThreadExecutor();
2.
3.
ExecutorService executorService2 = Executors.newFixedThreadPool(
10
);
4.
5.
ExecutorService executorService3 = Executors.newScheduledThreadPool(
10
);
01.
ExecutorService executorService = Executors.newSingleThreadExecutor();
02.
03.
executorService.execute(
new
Runnable() {
04.
public
void
run() {
05.
System.out.println(
"Asynchronous task"
);
06.
}
07.
});
08.
09.
executorService.shutdown();
1.
Future future = executorService.submit(
new
Runnable() {
2.
public
void
run() {
3.
System.out.println(
"Asynchronous task"
);
4.
}
5.
});
6.
7.
future.get();
//returns null if the task has finished correctly.
1.
Future future = executorService.submit(
new
Callable(){
2.
public
Object call()
throws
Exception {
3.
System.out.println(
"Asynchronous Callable"
);
4.
return
"Callable Result"
;
5.
}
6.
});
7.
8.
System.out.println(
"future.get() = "
+ future.get());
01.
ExecutorService executorService = Executors.newSingleThreadExecutor();
02.
03.
Set> callables =
new
HashSet>();
04.
05.
callables.add(
new
Callable() {
06.
public
String call()
throws
Exception {
07.
return
"Task 1"
;
08.
}
09.
});
10.
callables.add(
new
Callable() {
11.
public
String call()
throws
Exception {
12.
return
"Task 2"
;
13.
}
14.
});
15.
callables.add(
new
Callable() {
16.
public
String call()
throws
Exception {
17.
return
"Task 3"
;
18.
}
19.
});
20.
21.
String result = executorService.invokeAny(callables);
22.
23.
System.out.println(
"result = "
+ result);
24.
25.
executorService.shutdown();
01.
ExecutorService executorService = Executors.newSingleThreadExecutor();
02.
03.
Set> callables =
new
HashSet>();
04.
05.
callables.add(
new
Callable() {
06.
public
String call()
throws
Exception {
07.
return
"Task 1"
;
08.
}
09.
});
10.
callables.add(
new
Callable() {
11.
public
String call()
throws
Exception {
12.
return
"Task 2"
;
13.
}
14.
});
15.
callables.add(
new
Callable() {
16.
public
String call()
throws
Exception {
17.
return
"Task 3"
;
18.
}
19.
});
20.
21.
List> futures = executorService.invokeAll(callables);
22.
23.
for
(Future future : futures){
24.
System.out.println(
"future.get = "
+ future.get());
25.
}
26.
27.
executorService.shutdown();
如果你想要立即关闭 ExecutorService,你可以调用 shutdownNow() 方法。这样会立即尝试停止所有执行中的任务,并忽略掉那些已提交但尚未开始处理的任务。无法担保执行任务的正确执行。可能它们被停止了,也可能已经执行结束。
01.
int
corePoolSize =
5
;
02.
int
maxPoolSize =
10
;
03.
long
keepAliveTime =
5000
;
04.
05.
ExecutorService threadPoolExecutor =
06.
new
ThreadPoolExecutor(
07.
corePoolSize,
08.
maxPoolSize,
09.
keepAliveTime,
10.
TimeUnit.MILLISECONDS,
11.
new
LinkedBlockingQueue()
12.
);
但是,除非你确实需要显式为 ThreadPoolExecutor 定义所有参数,使用 java.util.concurrent.Executors 类中的工厂方法之一会更加方便,正如 ExecutorService 小节所述。
01.
ScheduledExecutorService scheduledExecutorService =
02.
Executors.newScheduledThreadPool(
5
);
03.
04.
ScheduledFuture scheduledFuture =
05.
scheduledExecutorService.schedule(
new
Callable() {
06.
public
Object call()
throws
Exception {
07.
System.out.println(
"Executed!"
);
08.
return
"Called!"
;
09.
}
10.
},
11.
5
,
12.
TimeUnit.SECONDS);
1.
ScheduledExecutorService scheduledExecutorService =
2.
3.
Executors.newScheduledThreadPool(
5
);
01.
ScheduledExecutorService scheduledExecutorService =
02.
Executors.newScheduledThreadPool(
5
);
03.
04.
ScheduledFuture scheduledFuture =
05.
scheduledExecutorService.schedule(
new
Callable() {
06.
public
Object call()
throws
Exception {
07.
System.out.println(
"Executed!"
);
08.
return
"Called!"
;
09.
}
10.
},
11.
5
,
12.
TimeUnit.SECONDS);
13.
14.
System.out.println(
"result = "
+ scheduledFuture.get());
15.
16.
scheduledExecutorService.shutdown();
你可以使用从 ExecutorService 接口继承来的 shutdown() 或 shutdownNow() 方法将 ScheduledExecutorService 关闭。参见 ExecutorService 关闭部分以获取更多信息。
1.
ForkJoinPool forkJoinPool =
new
ForkJoinPool(
4
);
01.
import
java.util.ArrayList;
02.
import
java.util.List;
03.
import
java.util.concurrent.RecursiveAction;
04.
05.
public
class
MyRecursiveAction
extends
RecursiveAction {
06.
07.
private
long
workLoad =
0
;
08.
09.
public
MyRecursiveAction(
long
workLoad) {
10.
this
.workLoad = workLoad;
11.
}
12.
13.
@Override
14.
protected
void
compute() {
15.
16.
//if work is above threshold, break tasks up into smaller tasks
17.
if
(
this
.workLoad >
16
) {
18.
System.out.println(
"Splitting workLoad : "
+
this
.workLoad);
19.
20.
List subtasks =
21.
new
ArrayList();
22.
23.
subtasks.addAll(createSubtasks());
24.
25.
for
(RecursiveAction subtask : subtasks){
26.
subtask.fork();
27.
}
28.
29.
}
else
{
30.
System.out.println(
"Doing workLoad myself: "
+
this
.workLoad);
31.
}
32.
}
33.
34.
private
List createSubtasks() {
35.
List subtasks =
36.
new
ArrayList();
37.
38.
MyRecursiveAction subtask1 =
new
MyRecursiveAction(
this
.workLoad /
2
);
39.
MyRecursiveAction subtask2 =
new
MyRecursiveAction(
this
.workLoad /
2
);
40.
41.
subtasks.add(subtask1);
42.
subtasks.add(subtask2);
43.
44.
return
subtasks;
45.
}
46.
47.
}
1.
MyRecursiveAction myRecursiveAction =
new
MyRecursiveAction(
24
);
2.
3.
forkJoinPool.invoke(myRecursiveAction);
01.
import
java.util.ArrayList;
02.
import
java.util.List;
03.
import
java.util.concurrent.RecursiveTask;
04.
05.
06.
public
class
MyRecursiveTask
extends
RecursiveTask {
07.
08.
private
long
workLoad =
0
;
09.
10.
public
MyRecursiveTask(
long
workLoad) {
11.
this
.workLoad = workLoad;
12.
}
13.
14.
protected
Long compute() {
15.
16.
//if work is above threshold, break tasks up into smaller tasks
17.
if
(
this
.workLoad >
16
) {
18.
System.out.println(
"Splitting workLoad : "
+
this
.workLoad);
19.
20.
List subtasks =
21.
new
ArrayList();
22.
subtasks.addAll(createSubtasks());
23.
24.
for
(MyRecursiveTask subtask : subtasks){
25.
subtask.fork();
26.
}
27.
28.
long
result =
0
;
29.
for
(MyRecursiveTask subtask : subtasks) {
30.
result += subtask.join();
31.
}
32.
return
result;
33.
34.
}
else
{
35.
System.out.println(
"Doing workLoad myself: "
+
this
.workLoad);
36.
return
workLoad *
3
;
37.
}
38.
}
39.
40.
private
List createSubtasks() {
41.
List subtasks =
42.
new
ArrayList();
43.
44.
MyRecursiveTask subtask1 =
new
MyRecursiveTask(
this
.workLoad /
2
);
45.
MyRecursiveTask subtask2 =
new
MyRecursiveTask(
this
.workLoad /
2
);
46.
47.
subtasks.add(subtask1);
48.
subtasks.add(subtask2);
49.
50.
return
subtasks;
51.
}
52.
}
1.
MyRecursiveTask myRecursiveTask =
new
MyRecursiveTask(
128
);
2.
3.
long
mergedResult = forkJoinPool.invoke(myRecursiveTask);
4.
5.
System.out.println(
"mergedResult = "
+ mergedResult);
在你计划在自己的项目里使用 ForkJoinPool 之前最好读一下该篇文章。
1.
Lock lock =
new
ReentrantLock();
2.
3.
lock.lock();
4.
5.
//critical section
6.
7.
lock.unlock();
unlock() 方法对 Lock 实例解锁。一个 Lock 实现将只允许锁定了该对象的线程来调用此方法。其他(没有锁定该 Lock 对象的线程)线程对 unlock() 方法的调用将会抛一个未检查异常(RuntimeException)。
01.
ReadWriteLock readWriteLock =
new
ReentrantReadWriteLock();
02.
03.
04.
readWriteLock.readLock().lock();
05.
06.
// multiple readers can enter this section
07.
// if not locked for writing, and not writers waiting
08.
// to lock for writing.
09.
10.
readWriteLock.readLock().unlock();
11.
12.
13.
readWriteLock.writeLock().lock();
14.
15.
// only one writer can enter this section,
16.
// and only if no threads are currently reading.
17.
18.
readWriteLock.writeLock().unlock();
注意如何使用 ReadWriteLock 对两种锁实例的持有。一个对读访问进行保护,一个队写访问进行保护。
1.
AtomicBoolean atomicBoolean =
new
AtomicBoolean();
1.
AtomicBoolean atomicBoolean =
new
AtomicBoolean(
true
);
1.
AtomicBoolean atomicBoolean =
new
AtomicBoolean(
true
);
2.
3.
boolean
value = atomicBoolean.get();
1.
AtomicBoolean atomicBoolean =
new
AtomicBoolean(
true
);
2.
3.
atomicBoolean.set(
false
);
1.
AtomicBoolean atomicBoolean =
new
AtomicBoolean(
true
);
2.
3.
boolean
oldValue = atomicBoolean.getAndSet(
false
);
1.
AtomicBoolean atomicBoolean =
new
AtomicBoolean(
true
);
2.
3.
boolean
expectedValue =
true
;
4.
boolean
newValue =
false
;
5.
6.
boolean
wasNewValueSet = atomicBoolean.compareAndSet(
7.
expectedValue, newValue);
本示例对 AtomicBoolean 的当前值与 true 值进行比较,如果相等,将 AtomicBoolean 的值更新为 false。
1.
AtomicInteger atomicInteger =
new
AtomicInteger();
1.
AtomicInteger atomicInteger =
new
AtomicInteger(
123
);
1.
AtomicInteger atomicInteger =
new
AtomicInteger(
123
);
2.
3.
int
theValue = atomicInteger.get();
1.
AtomicInteger atomicInteger =
new
AtomicInteger(
123
);
2.
3.
atomicInteger.set(
234
);
1.
AtomicInteger atomicInteger =
new
AtomicInteger(
123
);
2.
3.
int
expectedValue =
123
;
4.
int
newValue =
234
;
5.
atomicInteger.compareAndSet(expectedValue, newValue);
1.
AtomicInteger atomicInteger =
new
AtomicInteger();
2.
3.
4.
System.out.println(atomicInteger.getAndAdd(
10
));
5.
System.out.println(atomicInteger.addAndGet(
10
));
decrementAndGet() 将 AtomicInteger 的值减一,并返回减一后的值。getAndDecrement() 也将 AtomicInteger 的值减一,但它返回的是减一之前的值。
1.
AtomicLong atomicLong =
new
AtomicLong();
1.
AtomicLong atomicLong =
new
AtomicLong(
123
);
1.
AtomicLong atomicLong =
new
AtomicLong(
123
);
2.
3.
long
theValue = atomicLong.get();
1.
AtomicLong atomicLong =
new
AtomicLong(
123
);
2.
3.
atomicLong.set(
234
);
AtomicLong 类也有一个原子性的 compareAndSet() 方法。这一方法将 AtomicLong 实例的当前值与一个期望值进行比较,如果两种相等,为 AtomicLong 实例设置一个新值。AtomicLong.compareAndSet() 使用示例:
1.
AtomicLong atomicLong =
new
AtomicLong(
123
);
2.
3.
long
expectedValue =
123
;
4.
long
newValue =
234
;
5.
atomicLong.compareAndSet(expectedValue, newValue);
本示例新建了一个初始值为 123 的 AtomicLong。然后将 AtomicLong 的当前值与期望值 123 进行比较,如果相等的话,AtomicLong 的新值将变为 234。
1.
AtomicLong atomicLong =
new
AtomicLong();
2.
3.
4.
System.out.println(atomicLong.getAndAdd(
10
));
5.
System.out.println(atomicLong.addAndGet(
10
));
decrementAndGet() 将 AtomicLong 的值减一,并返回减一后的值。getAndDecrement() 也将 AtomicLong 的值减一,但它返回的是减一之前的值。
1.
AtomicReference atomicReference =
new
AtomicReference();
1.
String initialReference =
"the initially referenced string"
;
2.
AtomicReference atomicReference =
new
AtomicReference(initialReference);
1.
AtomicReference atomicStringReference =
2.
new
AtomicReference();
1.
String initialReference =
"the initially referenced string"
;
2.
AtomicReference atomicStringReference =
3.
new
AtomicReference(initialReference);
1.
AtomicReference atomicReference =
new
AtomicReference(
"first value referenced"
);
2.
3.
String reference = (String) atomicReference.get();
1.
AtomicReference atomicReference =
2.
new
AtomicReference(
"first value referenced"
);
3.
4.
String reference = atomicReference.get();