关于多线程:Java并发 – 线程没有完成循环

Java concurrency - threads not finishing loops

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

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
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语句进行调试时(在上面的代码中有注释),一切都按预期开始工作。

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

one 82067
two 82067

这实际上是一本书"头顶Java"(第二版)的代码难题,但是作者提供了与上面相同的代码作为对不同行为的解决方案。

书籍输出:(与以上代码相同)

one 98098 two 98099

书籍说明:

Threads from two different classes are updating the same object in a
third class, because both threads are accessing a single instance of
Accum.

综上所述,我的问题是:

  • 为什么每次我的代码输出都不同?
  • 为什么线程中的循环没有完成它们的工作?
  • 为什么我的输出与书中提供的不同?**
  • **-附加


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