在java中使用多个线程添加数字

时间:2018-01-27 05:15:19

标签: java multithreading parallel-processing calculator

我无法弄清楚我的代码在做什么,因为这是我第一次使用多个线程进行编码。首先,为了学习这种类型的编程,我决定编写一个使用8个线程来对数字求和的微型程序。然而,无论我做什么,似乎我的程序在计数= 10时永远不会停止,它继续向前。我正在计划使用8个线程来扩展我的程序以进行大型计算。但是,这些线程根本没有相关性。它们已经过了10级。我使用了同步方法。我试过锁。我试过同时实现这两个。无论如何,似乎线程仍在计算过去10.请参阅下面的我当前的代码。

public class calculator implements Runnable {

static int counter = 0;
static int sum = 0;

private synchronized static int getAndIncrement()
{
//  System.out.println("counter is  : " + counter);

    int temp = counter;
    counter = counter + 1;
    System.out.println("counter is now : " + counter);
    return temp;
}

private synchronized void addToSum(int value)
{
//  System.out.println("sum : " + sum + " value: " + value);
    sum += value;
}

@Override
public void run() 
{
    // TODO Auto-generated method stub
    while(counter < 10)
    {
        int tempVal = getAndIncrement();
        System.out.println("temp val : " + tempVal);
        addToSum(tempVal);
    //  System.out.println("sum is now : " + sum);

    }

}


}

这是我的主要方法:

    public static void main(String[] args)
{


    calculator[] calc = new calculator[8];
    Thread[] thread = new Thread[8];

    final long startTime = System.currentTimeMillis();

    for(int i = 0; i < 8; i++)
    {
        calc[i] = new calculator();
        thread[i] = new Thread(calc[i]);
        thread[i].start();
    }

    while(thread[0].isAlive() ||thread[1].isAlive() || thread[2].isAlive() || thread[3].isAlive() || thread[4].isAlive() || thread[5].isAlive() || thread[6].isAlive() || thread[7].isAlive())
    {}

    final long endTime = System.currentTimeMillis();
    System.out.println(calculator.sum);
    System.out.println("Execution time : " + (startTime - endTime));
}

我很感激帮助!

1 个答案:

答案 0 :(得分:1)

synchronized关键字采用对象  锁。这意味着synchronized的两个方法无法在同一个对象上执行 。但是,它们将在两个不同的对象上同时执行。

在您的示例中,您的代码有8个calculator对象。 synchronized方法对您没有帮助。每个线程使用它的独立对象。您可以完全删除synchronized关键字,并且您的代码在语义上是等效的。

要避免这种情况,请使用对象的原子版本(AtomicInt)或锁定对象本身:synchronized(counter){...}但要实现此目的,您必须将类型更改为{{1} }。