网络是个好东西,想学什么想用什么,一搜就基本能找到, 有时由于输入的关键词不佳, 难找到合适的结果, 有时干脆就是没有相关的网页(或者是问题太简单), 这样的时候自已难免会多花时间琢磨, 这些琢磨的结果, 对其他朋友是有益的,博客这种一对多的媒介,很适用于这样的传播.
对于个人而言,开博, 有利监督自已把所学所悟分享出来, 把自己生活工作的片段分享出来, 或是"晒"出来. 这是第二次开博,第一次是在 Davies(这个Blogger最近不太更新哦)开发的BlogXP上, 坚持开了大概半年有余,却由于种种主观原因, 放弃了对它的维护. 这次看看自己能坚持多久.
Concurrent Programming in Java™: Design Principles and Patterns 是本不错的书,其中不是教条式教你如何用线程,如何同步, 不是过多罗列具体的实现技巧, 而是从多线程的需求出发, 考虑实现1)分时计算2)提高运算速度这两种需求下应如何解决资源访问的问题. 今天看到一处说hand-over-hand lock的地方, 对于为什么使用这种lock不能理解, 为什么要hand-over-hand lock呢, 为什么不是single-hand lock, 又不是hand-over-hand-over-hand lock(同时lock三个对象), 而需要同时lock两个对象呢? 且先看书中的代码示例:
class
ListUsingMutex
{

static class Node {
Object item;
Node next;
Mutex lock = new Mutex(); // each node keeps its own lock
Node(Object x, Node n) { item = x; next = n; }
}

protected Node head; // pointer to first node of list

//Use plain synchronization to protect head field.
// (We could instead use a Mutex here too but there is no
// reason to do so.)

protected synchronized Node getHead() { return head; }

public synchronized void add(Object x) { // simple prepend

// for simplicity here, do not allow null elements
if (x == null) throw new IllegalArgumentException();

// The use of synchronized here protects only head field.
// The method does not need to wait out other traversers
// that have already made it past head node.

head = new Node(x, head);
}
boolean search(Object x) throws InterruptedException {
Node p = getHead();

if (p == null || x == null) return false;

p.lock.acquire(); // Prime loop by acquiring first lock.

// If above acquire fails due to interrupt, the method will
// throw InterruptedException now, so there is no need for
// further cleanup.

for (;;) {
Node nextp = null;
boolean found;

try {
found = x.equals(p.item);
if (!found) {
nextp = p.next;
if (nextp != null) {
try { // Acquire next lock
// while still holding current
nextp.lock.acquire();
}
catch (InterruptedException ie) {
throw ie; // Note that finally clause will
// execute before the throw
}
}
}
}
finally { // release old lock regardless of outcome
p.lock.release();
}

if (found)
return true;
else if (nextp == null)
return false;
else
p = nextp;
}
}

// ... other similar traversal and update methods ...
}

这个例子是讲链表的, 为什么要一下持有两个lock呢? 我们这样来想: lock是为了避免资源访问冲突的, 这种实现允许多线程访问链表中的单个元素(而不是将链表整个当成一个资源lock起来), 这样就可能有其它的线程来同时访问一个结点,可以在遍历的过程中不用保持链表与遍历开始时相同.但为什么不只用一个lock呢, 如果线程A得到一个结点的lock后取得它的next()(nextp = p.next())结点,接着就释放这个lock. 这时,另一线程可能将nextp删除, 而这里的遍历就会出问题,因为nextp已经不在链表中了.
更简单的说, 我们要明确共享资源的目的, 是要保证一次遍历过程中, 链表与开始遍历时的链表相同, 或是要保证链表遍历过程中的当前结点是此刻链表中的一个结点. 这里我们选择后者, 就需要两个lock.
对于个人而言,开博, 有利监督自已把所学所悟分享出来, 把自己生活工作的片段分享出来, 或是"晒"出来. 这是第二次开博,第一次是在 Davies(这个Blogger最近不太更新哦)开发的BlogXP上, 坚持开了大概半年有余,却由于种种主观原因, 放弃了对它的维护. 这次看看自己能坚持多久.
Concurrent Programming in Java™: Design Principles and Patterns 是本不错的书,其中不是教条式教你如何用线程,如何同步, 不是过多罗列具体的实现技巧, 而是从多线程的需求出发, 考虑实现1)分时计算2)提高运算速度这两种需求下应如何解决资源访问的问题. 今天看到一处说hand-over-hand lock的地方, 对于为什么使用这种lock不能理解, 为什么要hand-over-hand lock呢, 为什么不是single-hand lock, 又不是hand-over-hand-over-hand lock(同时lock三个对象), 而需要同时lock两个对象呢? 且先看书中的代码示例:












































































更简单的说, 我们要明确共享资源的目的, 是要保证一次遍历过程中, 链表与开始遍历时的链表相同, 或是要保证链表遍历过程中的当前结点是此刻链表中的一个结点. 这里我们选择后者, 就需要两个lock.