[英]Java Synchronized Method and Block
我正在尝试更全面地了解Java中多线程的同步。 我理解使用synchronized关键字背后的高级思想,以及它如何在线程之间提供互斥。
唯一的问题是,即使你删除了使用这个主题比我认为需要更混乱的synchronized关键字,我在网上和教科书中阅读的大多数例子仍能正常工作。
任何人都可以提供一个具体的例子,当不包括synchronized关键字时会产生错误的结果吗? 任何信息将不胜感激。
关于竞争条件的事情是,如果你没有进行适当的同步,它们不一定会发生 - 事实上,它经常会很好地工作 - 但是一年后,在半夜,你的代码将崩溃与一个你无法重现的完全不可预测的错误,因为该错误只是随机出现。
竞争条件是如此阴险,因为它们并不总是使程序崩溃,并且它们或多或少地随机触发。
您通常可以通过增加迭代次数来触发竞争条件。 这是一个简单的例子,可以处理100次和1000次迭代,但在10,000次迭代(有时)失败(至少在我的四核盒子上)。
public class Race
{
static final int ITERATIONS = 10000;
static int counter;
public static void main(String[] args) throws InterruptedException {
System.out.println("start");
Thread first = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < ITERATIONS; i++) {
counter++;
}
}
});
Thread second = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < ITERATIONS; i++) {
counter++;
}
}
});
first.start();
second.start();
first.join();
second.join();
System.out.println("Counter " + counter + " should be " + (2 * ITERATIONS));
}
}
>>> Counter 12325 should be 20000
此示例失败,因为未正确同步对counter
访问。 它可能以两种方式失败,可能在同一次运行中:
这个简单程序的修复方法是使用AtomicInteger
。 由于增量问题,使用volatile
是不够的,但AtomicInteger
提供了增量,获取和设置等的原子操作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.