比方说,我有两个核心的CPU。如果我将运行与Executors.newFixedThreadPool后台处理服务(4)线程是我纠正:与CPU核心的Java线程关系
- 执行服务单线程的一生中会在不同的内核
- 即使如果线程A运行不同步运行它的代码放在核心1上,然后在CPU缓存中留下一些共享单例的值,然后如果线程B会在相同的核心上运行它的代码,并且会尝试从同一个内存位置获得单值,它会从CPU核心L1或L2缓存中获取它。如果线程B将使用同步,它将从主内存(最新版本)读取新值。通常,如果CPU内核中的某个线程缓存了共享对象的专用字段的某个值 - 另一个可以在同一个内核上运行的线程可以从其他线程留下的缓存中看到私有成员的值。
- 如果上面的两个选项都是真的 - 如果L2缓存将用于存储线程之间的共享(这将增加新的值映射)HashMap实例和L2将在所有核心缓存之间共享 - 这是否意味着跳过不是原子操作(如果我们只想在地图中看到正确/最新的值),我们可以跳过同步。例如会是正确的有一个HashMap和跳跃从地图读取现有的值同步:
例
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
public class Launcher {
public static void main(String[] args) throws Exception {
final Stats stats = new Stats();
final Random key = new Random();
ExecutorService service = Executors.newFixedThreadPool(2);
service.submit(new Runnable() {
@Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
String keyValue = String.valueOf(key.nextInt(10));
int value = stats.inc(keyValue);
System.out.println("[A] Key " + keyValue + " was incremented to " + value);
try {
TimeUnit.MILLISECONDS.sleep(1500);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
});
service.submit(new Runnable() {
@Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
int[] values = new int[10];
for (int i = 0; i< 10; i++) {
values[i] = stats.get(String.valueOf(i));
}
System.out.println("[B] " + Arrays.toString(values));
try {
TimeUnit.MILLISECONDS.sleep(1500);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
});
}
static class Stats {
private final Map<String, Number> statistics = new HashMap<String, Number>();
public int inc(String key) {
if (!statistics.containsKey(key)) {
synchronized (statistics) {
statistics.put(key, new AtomicInteger(0));
}
}
return ((AtomicInteger) statistics.get(key)).getAndIncrement();
}
public int get(String key) {
if (!statistics.containsKey(key)) {
return 0;
}
return statistics.get(key).intValue();
}
}
}
你能指出我的多线程代码管理水平低下的一些有价值的文档java吗?
家伙,我真的明白,我们不应该提前
依赖于特定架构/ CPU /等我只是好奇,如果各点比0 :)THX更大的概率
当您执行Java时,请不要在二级高速缓存中考虑。这是一种抽象,可能会有不同的表现。如果你想重复使用每个线程的资源或不做任何超出[spec](http://docs.oracle.com/javase/specs/jls/se7/html/jls-17。)的假设,请使用'ThreadLocal'。 HTML)。 – zapl
“你能指点我一些关于java中低层管理多线程代码的有价值的文档吗?”点击上面评论中的“spec”。 – zapl
我认为有时候我们应该依赖于特定的架构:) – MariuszS