Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/303.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_Static - Fatal编程技术网

带和不带静态变量的Java同步

带和不带静态变量的Java同步,java,multithreading,static,Java,Multithreading,Static,我一直在研究java中的同步,并尝试运行以下程序 public class Example { public static void main(String[] args) { Counter counterA = new Counter(); Counter counterB = new Counter(); Thread threadA = new CounterThread(counter

我一直在研究java中的同步,并尝试运行以下程序

    public class Example {
        public static void main(String[] args) {
            Counter counterA = new Counter();
            Counter counterB = new Counter();
              Thread  threadA = new CounterThread(counterA);
              Thread  threadB = new CounterThread(counterB);

              threadA.start();
              threadB.start(); 
        }
    }

    class CounterThread extends Thread {
        protected Counter counter = null;

        public CounterThread(Counter counter){
           this.counter = counter;
        }
        public void run() {
        for(int i=0; i<2; i++){
              counter.add(i);
           }
        }
    }

    class Counter {
         long count = 0;
         public synchronized void add(long value){
          this.count += value;
          System.out.println(this.count);
        }
    }
但是如果我将counter类的count变量的access修饰符修改为static,如下所述:

    static long count = 0;
现在,如果尝试运行示例类,我会得到如下输出

 0
 1
 0
 2
 0
 1
 1
 2
但是当我调试示例类时,我得到的输出是

 0
 1
 0
 2
 0
 1
 1
 2
有人能帮我理解其中的区别吗。
提前感谢并致歉,因为我不熟悉多线程概念

每个实例都有自己的实例变量副本,但它们共享静态变量。由于您有两个类实例和两个线程在这些实例上操作:

        Counter counterA = new Counter();
        Counter counterB = new Counter();
        Thread  threadA = new CounterThread(counterA);
        Thread  threadB = new CounterThread(counterB);
因此,效果是明显的。当
计数
为非静态时,两个线程不会影响两个不同对象的
计数
。但是当
count
是静态的时,两个线程处理由两个实例共享的同一个变量


当您有两个独立的线程在运行时,执行顺序是动态的,这取决于线程调度器如何选择要执行的线程。使用调试器不一定会影响它,事实上,在正常执行程序时,您可能会看到不同的结果。

每个实例都有自己的实例变量副本,但它们共享静态变量。由于您有两个类实例和两个线程在这些实例上操作:

        Counter counterA = new Counter();
        Counter counterB = new Counter();
        Thread  threadA = new CounterThread(counterA);
        Thread  threadB = new CounterThread(counterB);
因此,效果是明显的。当
计数
为非静态时,两个线程不会影响两个不同对象的
计数
。但是当
count
是静态的时,两个线程处理由两个实例共享的同一个变量


当您有两个独立的线程在运行时,执行顺序是动态的,这取决于线程调度器如何选择要执行的线程。使用调试器不一定会影响它,事实上,在正常执行程序时,您可能会看到不同的结果。

synchronized
只会防止两个调用者同时在同一实例上输入方法。所以它基本上不会影响你的例子

非静态情况:每个线程都在更新自己的
计数器。count
实例。您可以将0-1-0-1或0-0-1-1(不太可能)作为输出

静态情况:每个线程都在更新相同的
计数器。通过两个不同的
计数器
实例进行计数。你可以得到0-0-1-2,0-1-1-2和0-1-0-2

为什么是最后一个选择?您只影响静态
Coutner.count
实例,而不影响静态
计数器
实例。因此,两个线程都可以在
计数器中。添加
时,一个线程可能已经加载了0以输出它,但其他线程随后会更新它并输出1,只有第一个线程才输出其0


您得到的0-0-1-2、0-1-1-2或0-1-0-2中的哪一个根本没有定义,并且不依赖于调试和发布模式。但是,由于编译器生成的汇编代码的差异,在调试和发布模式下收到不同的结果是很常见的。

synchronized
只会防止两个调用者同时在同一实例上输入方法。所以它基本上不会影响你的例子

非静态情况:每个线程都在更新自己的
计数器。count
实例。您可以将0-1-0-1或0-0-1-1(不太可能)作为输出

静态情况:每个线程都在更新相同的
计数器。通过两个不同的
计数器
实例进行计数。你可以得到0-0-1-2,0-1-1-2和0-1-0-2

为什么是最后一个选择?您只影响静态
Coutner.count
实例,而不影响静态
计数器
实例。因此,两个线程都可以在
计数器中。添加
时,一个线程可能已经加载了0以输出它,但其他线程随后会更新它并输出1,只有第一个线程才输出其0


您得到的0-0-1-2、0-1-1-2或0-1-0-2中的哪一个根本没有定义,并且不依赖于调试和发布模式。然而,由于编译器生成的汇编代码的差异,在调试和发布模式下收到不同的结果是很常见的。

但是如果计数是静态的,那么正常执行和调试程序执行应该给出相同的结果?@user3403462静态变量如何影响线程调度程序?没有意义,也没有连接。但是如果计数是静态的,那么正常执行和调试器执行应该给出相同的结果?@user34034462静态变量如何影响线程调度程序?没有意义,也没有联系。