【问题标题】:Incrementing and decremening a single shared variable with multiple Threads使用多个线程递增和递减单个共享变量
【发布时间】:2013-03-21 22:28:41
【问题描述】:

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

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

结果展示了一个例子:

  • 这是 Thread_4 迭代:-108 of 500
    这是 Thread_5 迭代:500 个中的 291 个
    这是 Thread_4 迭代:-109 of 500
    这是 Thread_4 迭代:-110 of 500

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

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

代码:- 共享变量类

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;
    }
}

----- 递增类

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();
}

【问题讨论】:

  • 不贴代码就无法判断
  • 输入您的代码,让我们更好地了解您的问题。
  • 预期输出是什么?

标签: java multithreading concurrency bluej


【解决方案1】:

考虑使用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();
    }
}

或使用同步方法:

public class Foo
{
    private volatile int counter;

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

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

    public int getValue()
    {
        return counter;
    }
}

【讨论】:

  • 我已经这样做了,但我仍然没有得到完全同步的递增和递减计数。 *****(这是 Thread_2 迭代:-9 of 500 这是 Thread_2 迭代:-8 of 500 这是 Thread_1 迭代:-135 of 500 这是 Thread_1 迭代:-7 of 500 这是 Thread_1 迭代:-6 of 500)
  • 是否可以在一种方法中同时运行递增和递减,而不是使用两种不同的方法?
【解决方案2】:

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

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

  1. 递增/递减
  2. 获取当前值
  3. 创建输出字符串
  4. 输出输出字符串

而另一个线程可能会在这些操作之间轮流。所以可能是 Thread_5 做了它该做的事情,然后其他线程开始轮流,过了一会儿 Thread_5 才输出结果。

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

【讨论】:

  • 我想我明白你的意思了,能举个例子吗?
  • 是否可以在一种方法中同时运行递增和递减,而不是使用两种不同的方法?
  • 只需将 System.out.println 放在 increment() 或 decrement() 内。如果要对两种操作使用一种方法,请使用方法参数来指示它是哪种操作。像操作(布尔增量)。
  • 谢谢.. 我试过了,但我仍然在线程中得到一些部分,这些部分仍然没有遵循 1 或 2 个线程可能具有随机值的顺序。
  • 您是只使用一种方法还是仍然使用两种方法?我刚刚意识到您必须只使用一个来实现排序。这应该会有所帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多