198. 如果线程 k + 2^r 比 线程 k 快很多,当线程 k + 2^r 读 a[k]的时候将读到没有 sum k段的原始值,没有求和的作用。
public void run() {
int d = 1, sum = 0;
while (d < N) {
if (i >= d)
sum = a[i-d];
b.await();
if (i >= d)
a[i] += sum;
b.await();
d = d * 2;
}}}
代码来自书作者ppt。
199.
package p199;
import java.util.concurrent.atomic.AtomicInteger;
public class SenseBarrier
{
private AtomicInteger count;
private final int size;
private boolean sense;
private ThreadLocal
threadSense;
public SenseBarrier(int n)
{
count = new AtomicInteger(n);
size = n;
sense = false;
threadSense = new ThreadLocal
()
{
protected Boolean initialValue() { return !sense; };
};
}
public void await()
{
boolean mySense = threadSense.get();
int position = count.getAndDecrement();
if(position == 1)
{
count.set(size);
sense = mySense;
this.notifyAll();
}else
{
while(sense != mySense)
{
try
{
this.wait();
}catch(InterruptedException e)
{
e.printStackTrace();
}
}
}
threadSense.set(!mySense);
}
}
当参与的线程行为不确定性强,响应时间要求不高,cpu不希望独占是采用wait的方式合适;否则采用spin比较合适。
200.
package ch17.basic;
import java.util.concurrent.atomic.AtomicInteger;
public abstract class TreeNode
{
protected AtomicInteger count;
protected TreeNode parent;
protected volatile boolean sense;
protected final int radix;
public TreeNode(int radix)
{
sense = false;
parent = null;
this.radix = radix;
count = new AtomicInteger(radix);
}
public TreeNode(int radix, TreeNode parent)
{
this(radix);
this.parent = parent;
}
public void nodeNotify()
{
return;
}
abstract public void await();
abstract public void build(int depth, Integer leaves, TreeNode leaf[]);
}
package ch17.p200;
import ch17.basic.Barrier;
import ch17.basic.TreeNode;
public class RunnableTree implements Barrier
{
final int radix;
Node[] leaf;
int leaves;
ThreadLocal
threadSense;
ThreadLocal
ThreadID;
Runnable task;
final int n;
public RunnableTree(int n, int radix, Runnable task)
{
this.radix = radix;
this.n = n;
leaves = 0;
threadSense = new ThreadLocal
()
{
protected Boolean initialValue() { return true; };
};
ThreadID = new ThreadLocal
()
{
protected Integer initialValue() { return 0; };
};
this.task = task;
build();
}
public void await()
{
int me = ThreadID.get();
Node myNode = leaf[me / radix];
myNode.await();
}
private void build()
{
leaf = new Node[n / radix];
int depth = 0;
int layNum = n;
while(layNum > 1)
{
depth ++;
layNum = layNum / radix;
}
Node root = new Node(radix);
Integer leaveNum = new Integer(0);
root.build(depth, leaveNum, leaf);
leaves = leaveNum;
}
private