FutureTask构建高效缓存

例子来源于Java并发编程实战,5.6 构建高效且可伸缩的结果缓存。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
public class Memoizer<A, V> implements Computable<A, V> {
private final ConcurrentMap<A, Future<V>> cache = new ConcurrentHashMap<A, Future<V>>();
private final Computable<A, V> c;

public Memoizer(Computable<A, V> c) {
this.c = c;
}

public V compute(final A arg) throws InterruptedException {
while (true) {
Future<V> f = cache.get(arg);
if (f == null) {
Callable<V> eval = new Callable<V>() {
public V call() throws InterruptedException {
return c.compute(arg);
}
};
FutureTask<V> ft = new FutureTask<V>(eval);
f = cache.putIfAbsent(arg, ft);
if (f == null) {
f = ft;
ft.run();
}
}
try {
return f.get();
} catch (CancellationException e) {
cache.remove(arg, f);
} catch (ExecutionException e) {
throw LaunderThrowable.launderThrowable(e.getCause());
}
}
}
}
阅读更多

线程同步

一、奇偶交替

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
public class PrintTest {
static volatile int count = 1;
public static void printZero() {
System.out.print("0");
}
public static void printOdd() {
System.out.print(count);
}
public static void printEven() {
System.out.print(count);
}

public static void print(int n) throws InterruptedException {
ReentrantLock lock = new ReentrantLock();
Condition zeroCond = lock.newCondition();
Condition oddCond = lock.newCondition();
Condition evenCond = lock.newCondition();

Thread zero = new Thread(() -> {
lock.lock();
while (count <= n) {
zeroCond.await();
if (count <= n) {
printZero();
}
if (count % 2 == 1) {
evenCond.signal();
} else {
oddCond.signal();
}
}
lock.unlock();
});
Thread odd = new Thread(() -> {
lock.lock();
while (count <= n) {
oddCond.await();
if (count > n) {
return;
}
printEven();
count++;
zeroCond.signal();
}
lock.unlock();
});

Thread even = new Thread(() -> {
lock.lock();
while (count <= n) {
evenCond.await();
if (count > n) {
return;
}
printOdd();
count++;
zeroCond.signal();
}
lock.unlock();
});

zero.start();
odd.start();
even.start();

lock.lock();
zeroCond.signal();
lock.unlock();

zero.join();
odd.join();
even.join();
}
}
阅读更多

synchronized

多线程访问相同的共享可变的变量时,通常需要使用加锁的方式实现同步,避免竞态条件发生。同步的其中一个特征就是互斥,通过使访问顺序串行化,使得并发结果合法和可预期。synchronized是java的关键字,其通过java的内置锁机制实现多线程同步。

一、synchronized的三种锁形态

阅读更多

volatile

volatile是对共享变量的修饰词,无法修饰局部变量。它保证了被修饰变量的可见性和禁止指令重排。

一、JMM和volatile

阅读更多