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

use*_*236 4 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();
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

这将是我的Thread类:

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

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

Gra*_*ray 9

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

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

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

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

public static AtomicInteger number = new AtomicInteger(0);
...
MainClass.number.incrementAndGet();
Run Code Online (Sandbox Code Playgroud)

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

  • 发生的情况是两个线程在其本地缓存内存中具有不同版本的共享对象。请记住,所有 CPU 更新都会被缓存。如果 2 个 CPU 尝试同时更新相同的 _central_ 内存行,那么由于内存锁定,其中一个会获胜。第二次更新将获胜。@乔治梅杰 (2认同)