1

我编写了一个多线程和同步递增函数,但它没有显示一致的输出:-

$ java Main
count: 999883

$ java Main
count: 1000000

$ java Main
count: 999826

$ java Main
count: 1000000

$ java Main
count: 1000000

我有一个同步计数器:-

public class Counter {
    public int count;
    synchronized void inc() {
        count = count+1;
    }
    int getCount() {
        return count;
    }
}

使用计数器对象初始化并将其递增 1000 次的线程类:-

public class CountPrimesRunnable implements Runnable {
    private Counter c;

    public CountPrimesRunnable(Counter c) {
        this.c = c;
    }

    public void run() {
        for (int i = 0; i < 1000; i++)
            c.inc();
    }
}

以及一次创建 1000 个线程的 Main 类:-

public class Main {
    public static void main(String[] args) {
        int numberOfThreads = 1000;
        Thread[] worker = new Thread[numberOfThreads];
        Counter c = new Counter();
        for (int i = 0; i < numberOfThreads; i++)
            worker[i] = new Thread(new CountPrimesRunnable(c));

        for (int i = 0; i < numberOfThreads; i++)
            worker[i].start();

        System.out.println("count: " + c.count);
    }
}

我错过了什么?

4

2 回答 2

4

但它没有显示一致的输出:-

那是因为,从您的代码中不确定main线程​​是否会在所有其他线程完成工作后始终完成。在某些情况下,您得到的结果小于1000000,是一些线程在主线程完成后仍然执行的情况。

您可以在每个新创建的线程上调用Thread#join() 方法,以确保该main方法等待所有这些线程死亡,然后在 for 循环之后继续执行。

因此,您必须添加另一个 for 循环以join在每个启动的线程上调用,并且您可以通过将其与第一个循环合并来避免使用第二个 for 循环:

for (int i = 0; i < numberOfThreads; i++) {
    worker[i] = new Thread(new CountPrimesRunnable(c));
    worker[i].start();
}

for (int i = 0; i < numberOfThreads; i++) {
    worker[i].join();
}

当您从 a 内部调用 a 时join,只有在死亡后才会继续进一步执行。Thread AThread BThread BThread A

于 2013-02-17T06:00:49.607 回答
1
public class Counter {
    public int count;
    synchronized void inc() {
        count = count+1;
    }

    //this method must also be synchronized for establishing the happens-before relationship
    synchronized int getCount() {
        return count;
    }
}

只有当 get 和 set在同一个 lock上同步时,才能保证看到最新的值。

您还需要调用 join 并等待所有线程完成执行。

于 2013-02-17T06:11:26.470 回答