mirror of
https://github.com/glen9527/Clean-Code-zh.git
synced 2025-12-17 18:54:23 +08:00
标题 & 代码高亮
This commit is contained in:
18
docs/ch13.md
18
docs/ch13.md
@@ -1,4 +1,4 @@
|
||||
Concurrency
|
||||
# 第 13 章 Concurrency
|
||||
by Brett L. Schuchert
|
||||
|
||||
Image
|
||||
@@ -56,7 +56,7 @@ Here are a few more balanced sound bites regarding writing concurrent software:
|
||||
|
||||
CHALLENGES
|
||||
What makes concurrent programming so difficult? Consider the following trivial class:
|
||||
|
||||
```java
|
||||
public class X {
|
||||
private int lastIdUsed;
|
||||
|
||||
@@ -64,7 +64,7 @@ What makes concurrent programming so difficult? Consider the following trivial c
|
||||
return ++lastIdUsed;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
Let’s say we create an instance of X, set the lastIdUsed field to 42, and then share the instance between two threads. Now suppose that both of those threads call the method getNextId(); there are three possible outcomes:
|
||||
|
||||
• Thread one gets the value 43, thread two gets the value 44, lastIdUsed is 44.
|
||||
@@ -295,7 +295,7 @@ Hand-Coded
|
||||
You can insert calls to wait(), sleep(), yield(), and priority() in your code by hand. It might be just the thing to do when you’re testing a particularly thorny piece of code.
|
||||
|
||||
Here is an example of doing just that:
|
||||
|
||||
```java
|
||||
public synchronized String nextUrlOrNull() {
|
||||
if(hasNext()) {
|
||||
String url = urlGenerator.next();
|
||||
@@ -305,7 +305,7 @@ Here is an example of doing just that:
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
```
|
||||
The inserted call to yield() will change the execution pathways taken by the code and possibly cause the code to fail where it did not fail before. If the code does break, it was not because you added a call to yield().17 Rather, your code was broken and this simply made the failure evident.
|
||||
|
||||
17. This is not strictly the case. Since the JVM does not guarantee preemptive threading, a particular algorithm might always work on an OS that does not preempt threads. The reverse is also possible but for different reasons.
|
||||
@@ -326,14 +326,14 @@ Clearly, if we divide our system up into POJOs that know nothing of threading an
|
||||
|
||||
Automated
|
||||
You could use tools like an Aspect-Oriented Framework, CGLIB, or ASM to programmatically instrument your code. For example, you could use a class with a single method:
|
||||
|
||||
```java
|
||||
public class ThreadJigglePoint {
|
||||
public static void jiggle() {
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
You can add calls to this in various places within your code:
|
||||
|
||||
```java
|
||||
public synchronized String nextUrlOrNull() {
|
||||
if(hasNext()) {
|
||||
ThreadJiglePoint.jiggle();
|
||||
@@ -345,7 +345,7 @@ You can add calls to this in various places within your code:
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Now you use a simple aspect that randomly selects among doing nothing, sleeping, or yielding.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user