5

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

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

这将是我的线程类:

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

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

4

2 回答 2

11

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

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

尽管这会处理内存同步,但它不一定能保护您免受竞争条件的影响。同样重要的是要意识到这++实际上是 3 个操作:获取当前值,递增它,然后再次存储它。如果多个线程尝试执行此操作,则存在可能导致操作丢失的线程竞争条件。++

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

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

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

于 2013-02-20T15:40:17.937 回答
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());

        }
    }
于 2016-02-15T12:30:19.447 回答