obe*_*ger 8 java multithreading synchronization volatile thread-safety
假设我有以下类会被大量读取,但只是偶尔写入.它将用于多线程Web应用程序,因此它需要是线程安全的:
public class Foo {
private volatile String foo;
public String getFoo() {
return foo;
}
public synchronized String setFoo(String in) {
this.foo = in;
}
}
Run Code Online (Sandbox Code Playgroud)
Java Concurrency(http://www.ibm.com/developerworks/java/library/j-jtp06197/index.html)指出,这是一种在提高读访问权限的同时保护写访问的脆弱方法.什么是这种模式的更强的替代品?或者,如果foo在读取繁重的环境中需要变量,还是其他任何选择?谢谢.
Evg*_*eev 15
Volatile提供对字段的快速线程安全无锁访问,无需同步
private volatile String foo;
public String getFoo() {
return foo;
}
public void setFoo(String in) {
this.foo = in;
}
Run Code Online (Sandbox Code Playgroud)
volatile解决了3个问题1)内存可见性2)双字段和长字段的原子写入3)禁止指令重新排序.但是,如果你需要在一个字段上进行多次操作作为一个原子事务,例如增量,那就不够了.这段代码坏了
private volatile int id;
public void incrementId() {
id++;
}
Run Code Online (Sandbox Code Playgroud)
因为如果2个线程同时读取并递增它并保存结果,那么第一个增量的结果将被第二个增量的结果覆盖.为了防止这种情况发生,我们需要使用同步
private int id;
public synchronized int nextId() {
return ++id;
}
Run Code Online (Sandbox Code Playgroud)
或java.util.concurrent.atomic包
private AtomicInteger id = new AtomicInteger();
public void incrementId() {
return id.incrementAndGet();
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5409 次 |
| 最近记录: |