变量的同步
问题描述:
在这个程序中,对象jai
被一个线程访问,同时它也被另一个线程修改。这是正确的工作方式吗?是否不需要使对象同步?变量的同步
public class SameObjectModification {
private static int i = 0;
private static Jai jai;
static class Jai {
private final int a;
public Jai(int a) {
this.a = a;
}
public void print() {
System.out.println("value ==> " + a);
}
}
public static void main(String[] args) {
Thread t1 = new Thread() {
@Override
public void run() {
while (true) {
if (jai != null)
jai.print();
}
}
};
Thread t2 = new Thread() {
@Override
public void run() {
while (true) {
jai = new Jai(i++);
}
}
};
t1.start();
t2.start();
}
}
答
目前尚不清楚你试图达到什么目标,但是你可以通过使用原子来获得每个Jai的唯一值。
private static AtomicInteger i = new AtomicInteger(0);
private static Jai jai;
static class Jai {
private int a;
public Jai() {
this.a = i.incrementAndGet();
}
答
这thrade保存例如
private static int i = 0;
private static AtomicReference<Jai> jai = new AtomicReference<Jai>();
static class Jai {
private final int a;
public Jai(int a) {
this.a = a;
}
public void print() {
System.out.println("value ==> " + a);
}
}
public static void main(String[] args) {
Thread t1 = new Thread() {
@Override
public void run() {
while (true) {
Jai tmp = jai.get();
if (tmp != null)
tmp.print();
}
}
};
Thread t2 = new Thread() {
@Override
public void run() {
while (true) {
jai.set(new Jai(i++));
}
}
};
t1.start();
t2.start();
}
的版本,但实现取决于porpose。 您应该只对不可变或线程安全的类使用AtomicReference。
在其他情况下,您可以使用不同的锁,易失性字段,不同的原子实现(如AtomicLong)或同步。
但是你应该记住一个比锁和一个锁更快的原子比同步更快。
答
实际上,变量jai
依次引用许多对象。在第二个线程的循环的每次迭代中,都会创建一个新对象并将其分配给该变量。所以,在jai
上同步将无济于事。
如果你想确保由t2
线程创建的所有对象由t1
处理,你需要或者锁T1,等待t2
创建对象或使用一种队列。阅读关于java.util.concurrent.BlockingQueue。
更一般地,这是Producer-Consumer问题的一个例子。
你想达到什么目的? – aioobe 2015-02-23 10:22:09
不,不是。您正在从不同的线程访问状态。所以你会有可见性问题。 – 2015-02-23 10:23:39
这取决于你想要的。如果你想实现互斥,那么你必须同步它。 – 2015-02-23 10:39:06