是IF语句和循环,例如while和do while并发编程中的原子指令吗?
如果没有,有没有办法以原子方式实现它们?
编辑:修正了我的一些狡猾的英语。
答案 0 :(得分:0)
这些可以任意大&需要计算的复杂(即非原子)布尔表达式。防止涉及他们的竞争条件的一种方法(如果你的意思是"安抚")是使用某种锁定机制。
答案 1 :(得分:0)
在Java中,唯一没有任何额外工作的原子是分配。其他任何事情都需要通过声明方法synchronized
或使用synchronized
块进行同步。您还可以使用java.concurrent
中的类 - 其中一些使用一些更聪明的机制来确保同步,而不是仅仅声明方法synchronized
往往会很慢。
关于if-statement以及您在评论中询问的有关比较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
将导致NullPointerException
t1
获取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
?