Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/322.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
java对基本变量的多线程访问_Java_Multithreading_Primitive Types - Fatal编程技术网

java对基本变量的多线程访问

java对基本变量的多线程访问,java,multithreading,primitive-types,Java,Multithreading,Primitive Types,我知道,从不同线程同时访问同一对象,而不进行同步,通常是一件坏事。但是这个案子呢 我有多个线程在运行(考虑两个线程,ThreadA和ThreadB)。我还有一个静态类来记录线程做某事的次数 public class Counter { static private int counter=0; static public void incCounter() { counter++; } } 如果ThreadA和ThreadB都调用Counter.incCounter(),会

我知道,从不同线程同时访问同一对象,而不进行同步,通常是一件坏事。但是这个案子呢

我有多个线程在运行(考虑两个线程,ThreadA和ThreadB)。我还有一个静态类来记录线程做某事的次数

public class Counter {
  static private int counter=0;
  static public void incCounter() {
    counter++;
  }
}
如果ThreadA和ThreadB都调用Counter.incCounter(),会发生什么情况?

这不安全

每个线程将尝试读取
计数器
,向其添加一个计数器,然后写回结果。您无法保证这些读取和写入的顺序,甚至无法保证结果对每个线程都是可见的

特别是,一种失败情况是每个线程读取值0,将其递增为1,然后写回值1。即使在两个线程尝试递增计数器值后,这也会使计数器值为1


考虑改用.incrementAndGet()。

不管它是静态对象还是实例:如果从多个线程中更改它,就会出现问题。

它的值将是1或2。在此上下文中,静态变量和非静态变量之间没有区别。

为避免冲突,请使用关键字synchronized

public class Counter {
  static private int counter=0;
  public static synchronized void incCounter() {
      counter++;
  }
}

此关键字只允许一个线程调用incCounter()。

Dave是正确的,但快速修复方法只是将“synchronized”关键字添加到该方法描述中;如果多个线程调用该方法,它们将在方法边界处阻塞,直到其中一个(赢得比赛的)增加并存在,然后第二个调用方将进入

这很像在单例类上设计一个好的“getInstance()”方法;您通常希望它被同步,这样您就不会出现这样的情况:2个以上的线程进入该方法,所有线程都看到“instance”为null,然后所有线程都创建一个新实例,将其分配给本地成员并返回它

在这种情况下,您的线程可能会以对“相同”实例的不同引用结束。因此,同步代码块,仅允许第一个线程在实例为null时创建实例,否则总是向所有调用方返回相同的实例

if(instance==null)检查加上返回值很便宜;在微秒的数量级上,我相信将来调用getInstance(或者在您的示例incCounter中)时,不需要回避synchronized关键字(如果需要);这就是为什么


也就是说,如果你不能抽出几微秒。。。那么,你可能用错了语言:

没有什么灾难性的,但计数器将不是准确的总和。@不名誉:取决于你所认为的“灾难性”。如果某个关键的东西依赖于计数器,它将失败。为什么从不同线程访问同一个对象是一件坏事?“若需要,那个么它是必要的。”Steve Kuo-question澄清说,不同步的并发访问是不好的。显然,从多个线程进行适当的协调访问是不行的。对于轻量级性能计数器,我不使用任何类型的线程安全性,因为我知道计数器可能会稍微超出范围,但它的成本最低。这个计数器只是用来表示。嗯,我不知道它的存在。每天都是上学的日子。谢谢。这将起作用,但与
AtomicInteger
相比效率较低。