java 使用多个线程递增和递减单个共享变量

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15733434/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 20:41:35  来源:igfitidea点击:

Incrementing and decremening a single shared variable with multiple Threads

javamultithreadingconcurrencybluej

提问by user2075927

When incrementing and decrementing multiple threads using a single shared variable, how can I ensure that the threads count in a syncronized way and don't skip any value.

当使用单个共享变量递增和递减多个线程时,如何确保线程以同步方式计数并且不跳过任何值。

I have created a seperate class in which I have 3 different methods, one to increment, another to decrement and the last one to return the value. they are all synchronized as well.

我创建了一个单独的类,其中有 3 种不同的方法,一种是递增,另一种是递减,最后一种是返回值。它们也是同步的。

The result shows an example:

结果显示了一个示例:

  • This is Thread_4 iteration: -108 of 500
    This is Thread_5 iteration: 291 of 500
    This is Thread_4 iteration: -109 of 500
    This is Thread_4 iteration: -110 of 500
  • 这是 Thread_4 迭代:-108 of 500
    这是 Thread_5 迭代:291 of 500
    这是 Thread_4 迭代:-109 of 500
    这是 Thread_4 迭代:-110 of 500

As you can see the threads are decrementing but then it jumps to "291" which should not happen as I am using a shared variable.

如您所见,线程正在递减,但随后跳转到“291”,这在我使用共享变量时不应该发生。

*******************EDIT********

** *** *** *** *** *****编辑*** *****

CODE:- SHARED VARIABLE CLASS

代码:- 共享变量类

public class shareVar extends Thread
{
    private static int sharedVariable = 0;


    public synchronized static void increment(){
        sharedVariable++;
    }

    public synchronized static void decrement(){
        sharedVariable--;
    }

    public  static int value(){
        return sharedVariable;
    }
}

----- Incrementing Class

----- 递增类

sVar incrementVal = new sVar();

public synchronized void display(){

    for(int countVal = 0; countVal<=max; countVal++ ){
            incrementVal.increment();
            System.out.println("This is " + threadName + " iteration: " + incrementVal.value() + " of " + max);
            //this.yield();
    }
    System.out.println("*THIS " + threadName + " IS FINISH " 
                                    + "INCREMENTING *");

}

public void run(){

    display();
}

回答by Eng.Fouad

Consider using AtomicInteger:

考虑使用AtomicInteger

public class Foo
{
    private AtomicInteger counter = new AtomicInteger(0);

    public void increment()
    {
        counter.incrementAndGet();
    }

    public void decrement()
    {
        counter.decrementAndGet();
    }

    public int getValue()
    {
        return counter.get();
    }
}


or using the synchronized methods:

或使用同步方法:

public class Foo
{
    private volatile int counter;

    public synchronized void increment()
    {
        counter++;
    }

    public synchronized void decrement()
    {
        counter--;
    }

    public int getValue()
    {
        return counter;
    }
}

回答by fish

Not sure if I understand your question correctly, but your output looks the way it is just because another thread (Thread_4) gets to work on the value before Thread_5 outputs it.

不确定我是否正确理解您的问题,但您的输出看起来只是因为另一个线程 (Thread_4) 在 Thread_5 输出它之前开始处理该值。

There are a number of operations going on in each iteration (simplified list, in reality there are more than these):

每次迭代都会进行许多操作(简化列表,实际上不止这些):

  1. Increment/decrement
  2. Get the current value
  3. Create the output String
  4. Output the output String
  1. 递增/递减
  2. 获取当前值
  3. 创建输出字符串
  4. 输出输出字符串

And another thread may get a turn between any of these operations. So it could be that Thread_5 does what it does, then other threads get turns and only after a while Thread_5 outputs the result.

另一个线程可能会在这些操作中的任何一个之间轮流。所以可能是 Thread_5 做它所做的,然后其他线程轮流,只有在一段时间后 Thread_5 输出结果。

If you want the new values to be output in order, you need to output the current value inside the synchronized block, ie. the increment/decrement methods.

如果要按顺序输出新值,则需要在同步块内输出当前值,即。递增/递减方法。