具体代码在:这里(求打星!)
在课堂上我们学到了四种确保threadsafe的方法:
1.Confinement:限制数据共享. Don’t share the variable between threads.
2.Immutability:共享不可变数据. Make the shared data immutable.
3.Threadsafe data type:共享线程安全的可变数据. Encapsulate the shared data in an existing threadsafe data type that does the coordination for you.
4.Synchronization:同步机制:通过锁的机制共享线程不安全的可变数据,变并行为串行. Use synchronization to keep the threads from accessing the variable at the same time. Synchronization is what you need to build your own threadsafedata type.
Confinement在代码中的体现:
在Monkey类中限制数据共享.
Immutability在代码中的体现:
Logger类的log作为可共享的不可变数据
Threadsafe data type在代码中的体现:
共享线程安全的Collections.synchronizedMap:
Synchronization 在代码中的体现:
选择梯子时要对梯子上锁:
对梯子内的会引发冲突的方法加锁:
/**
* 让猴子从左岸上楼梯(此时要对该方法上锁).
*/
public synchronized void upfromL(Monkey monkey) {
if (ladder.get(1) == null) {
ladder.replace(1, monkey);
log.info(monkey + " climb the ladder from L.");
}
}
/**
* 让猴子从右岸上楼梯(此时要对该方法上锁).
*/
public synchronized void upfromR(Monkey monkey) {
if (ladder.get(ladder.size()) == null) {
ladder.replace(ladder.size(), monkey);
log.info(monkey + " climb the ladder from L.");
}
}
/**
* 模拟猴子在梯子上移动的方法.
*
* @return 移动的终点(如果超出梯子范围返回-1).
*/
public synchronized int move(String direction, int from, int distance) {
int end = from;
if (direction.equals("L->R")) {
for (int i = 1; i <= distance; i++) {
if (from + i > ladder.size()) {
end = -1;
break;
} else if (ladder.get(from + i) != null) {
end = from + i - 1;
break;
} else {
end = from + i;
}
}
} else {
for (int i = 1; i <= distance; i++) {
if (from - i <= 0) {
end = -1;
break;
} else if (ladder.get(from - i) != null) {
end = from - i + 1;
break;
} else {
end = from - i;
}
}
}
if (end == -1) {
ladder.replace(from, null);
} else if (end != from) {
ladder.replace(end, ladder.get(from));
ladder.replace(from, null);
}
return end;
}
对用于记录的全局变量变化时要上锁: