在并发编程中,IF语句和循环(如while或do while原子指令)是吗?
如果没有,是否有办法以原子方式实现它们?
编辑:修正了我的一些狡猾的英语。
发布于 2015-11-03 10:24:56
在Java中,没有额外工作的唯一原子性的东西是赋值。其他任何东西都需要同步,要么通过声明方法synchronized,要么使用synchronized块。您还可以使用来自java.concurrent的类--其中一些类使用一些更聪明的机制来确保同步,而不仅仅是声明synchronized方法(可能比较慢)。
关于if-语句和您在评论中提出的关于比较n == m的问题
比较不是原子的。首先必须加载n的值(在这里,m的值仍然可以更改),然后必须加载m的值,然后计算实际的比较(此时n和m的实际值可能已经与比较中的实际值不同)。
如果你想让它同步,你必须做这样的事情:
public class Test {
private static final Object lock = new Object();
public static void main(String[] args) {
if (equals(1, 2)) {
// do something (not synchronised)
}
}
public static boolean equals(int n, int m) {
synchronized (lock) {
return n == m;
}
}
}然而,这引发了一个问题,,为什么要执行这个,锁应该是什么(以及与锁共享的线程)?我希望看到更多关于你的问题的背景,因为目前我看不到做这种事情的任何理由。
你还应该记住:
Integer)null将导致NullPointerExceptiont1获取new Integer(1)上的锁,而t2获取new Integer(2)上的锁。因此,即使两个线程都锁定了n,它们仍然可以并行执行。public class Test {
private static Integer n = 1;
public static void main(String[] args) throws Exception {
Thread t1 = new Thread(() -> {
synchronized (n) {
System.out.println("thread 1 started");
sleep(2000);
System.out.println("thread 1 finished");
}
});
Thread t2 = new Thread(() -> {
synchronized (n) {
System.out.println("thread 2 started");
sleep(2000);
System.out.println("thread 2 finished");
}
});
t1.start();
sleep(1000);
n = 2;
t2.start();
t1.join();
t2.join();
}
private static void sleep(int millis) {
try {
Thread.sleep(millis);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}您考虑过使用可变的AtomicInteger吗?
发布于 2015-10-31 19:24:42
它们可以具有任意大的和复杂的(即非原子的)布尔表达式,需要进行计算。防止比赛条件涉及到他们(如果这就是你所说的“安抚”的意思)的一种方法是使用某种锁定机制。
https://stackoverflow.com/questions/33455614
复制相似问题