Java并发 - 线程没有完成循环

问题描述 投票:0回答:1

我正在学习Java中的并发基础知识,我在下面的例子中遇到了一个问题。有两个线程应该并发运行并完成它们在某些全局静态对象上运行的循环。我预计一个线程可以在另一个线程之前完成并打印不同的值,但我没想到会看到两个线程都打印相同的值,这表明它们在打印输出之前都没有完成它们的循环。

码:

public class TestThreads {
    public static void main(String[] args) {
        ThreadOne t1 = new ThreadOne();
        ThreadTwo t2 = new ThreadTwo();
        Thread one = new Thread(t1);
        Thread two = new Thread(t2);
        one.start();
        two.start();
    }
}

class Accum {
    private static Accum a = new Accum();
    private int counter = 0;
    private Accum() { 

    }
    public static Accum getAccum() {
        return a;
    }
    public int getCount() {
        return counter;
    }
    public void updateCounter(int add) {
        counter += add;     
    }
}

class ThreadOne implements Runnable {
    Accum a = Accum.getAccum();
    public void run() {
        for(int x=0; x < 98; x++) {
            a.updateCounter(1000);
            try {           
                Thread.sleep(50);
            } catch(InterruptedException ex) { }
            //System.out.println("index in one = " + x);
        }           
        System.out.println("one " + a.getCount());
    }
}

class ThreadTwo implements Runnable {
    Accum a = Accum.getAccum();
    public void run() {
        for(int x=0; x < 99; x++) {
            a.updateCounter(1);     
            try {
                Thread.sleep(50);
            } catch(InterruptedException ex) { }
            //System.out.println("index in two = " + x);
        }
        System.out.println("two " + a.getCount());
    }
}

为什么会这样?当我尝试使用print语句进行调试时(在上面的代码中注释),一切都按预期开始工作。

我的输出:(每次都不一样,这也很奇怪)

一个82067两个82067

这实际上是书“Head First Java”(第2版)中的代码拼图,但作者提供了与上述相同的代码作为不同行为的解决方案。

图书输出:(与上面相同的代码)

一个98098两个98099

书籍说明:

来自两个不同类的线程正在更新第三个类中的同一个对象,因为两个线程都在访问Accum的单个实例。

总之,我的问题是:

  1. 为什么我的代码输出每次都不同?
  2. 为什么线程中的循环没有完成他们的工作?
  3. 为什么我的输出与书中提供的不同?**

** - 补充

java multithreading concurrency
1个回答
2
投票

不知道这本书是如何工作的,但你的Accum实例不是线程安全的。因此,每次运行它都可以获得不同的答案。如果使updateCounter()和getCount()同步,它应该可靠地工作。

© www.soinside.com 2019 - 2024. All rights reserved.