使多个线程使用并更改相同的变量

时间:2013-02-20 15:37:50

标签: java multithreading

在我的程序中我需要使用多个线程并编辑相同的变量,但它似乎不起作用。这是我的意思的一个例子,这将是我的主要课程。

public class MainClass {

  public static int number = 0;
  public static String num = Integer.toString(number);

  public static void main(String[] args) {
    Scanner in = new Scanner(System.in);
    System.out.println("Enter number of threads.");
    int threads = in.nextInt();
    for (int n = 1; n <= threads; n++) {
      java.lang.Thread t = new Thread();
      t.start();
    }
  }
}

这将是我的Thread类:

public class Thread extends java.lang.Thread
{
  public void run()
  {
      MainClass.number++;
      System.out.println("Thread started");
      System.out.println(MainClass.num);
  }
}

我当场写了这段代码,所以可能会有一些错误,但没关系。我的程序基本上需要做这样的事情,但不是每次打印数字加1,所有线程只是打印相同的数字,0,多次。请帮助我,谢谢。

2 个答案:

答案 0 :(得分:9)

  

在我的程序中,我需要使用多个线程并编辑相同的变量,但它似乎不起作用......

任何时候多个线程正在更新同一个变量,您需要担心内存同步。线程获得高性能的方法之一是因为每个线程都使用本地CPU内存缓存,因此可能使用过时的变量副本。您需要使用synchronizedvolatile关键字强制线程的缓存将任何更新写入中央存储或从中央更新其缓存。

虽然这会处理内存同步,但它并不一定能保护您免受竞争条件的影响。同样重要的是要意识到++实际上是3个操作:获取当前值,增加它并再次存储它。如果多个线程尝试执行此操作,则thread race-conditions会导致错过++操作。

在这种情况下,您应该使用包含AtomicInteger字段的volatile int类。它为您提供了像incrementAndGet()这样的方法,它们以线程安全的方式完成递增该字段的工作。

public static AtomicInteger number = new AtomicInteger(0);
...
MainClass.number.incrementAndGet();

然后,多个线程可以安全地递增相同的变量。

答案 1 :(得分:0)

你去......

 import java.util.Scanner;
    import java.util.concurrent.atomic.AtomicInteger;

    public class UpdateVariables
    {
        static int num = 0;
        public static AtomicInteger  atomicInteger = new AtomicInteger(num);


        @SuppressWarnings("resource")
        public static void main(String args[])
        {
            Scanner userInput = new Scanner(System.in);
            System.out.println("Enter Number of Threads: ");
            int getThreadNumber = userInput.nextInt();
            for(int i = 0; i < getThreadNumber; i++)
            {
                PrintThread p = new PrintThread();
                p.start();
            }

        }

    }

    class PrintThread extends Thread
    {
        public void run()
        {
            System.out.println("Thread Started: ");
            System.out.println(UpdateVariables.atomicInteger.incrementAndGet());

        }
    }