奇怪的java并发行为

zap*_*dlo -4 java concurrency

我有以下代码:

class Hi
{
   public static void main (String [] args)
   {
      int a = 1;
      for (int i = 0; i < 50; i++) {
          a = a + i;
          System.out.println ("a before sleep is " + a);
          try {
              Thread.sleep(4000);
          } catch (InterruptedException e) {

          }
          System.out.println ("a after sleep is " + a);
      }
   }
}
Run Code Online (Sandbox Code Playgroud)

我打开两个控制台窗口并java Hi在第一个窗口中执行.然后等待大约10秒钟,并在第二个窗口中执行相同操作.两个输出都是相同的:

a before sleep is 1
a after sleep is 1
a before sleep is 2
a after sleep is 2
a before sleep is 4
a after sleep is 4
a before sleep is 7
a after sleep is 7
a before sleep is 11
a after sleep is 11
Run Code Online (Sandbox Code Playgroud)

没有交错.那么,如果我甚至不打扰使用synchronized语句,那么并发问题会引起什么样的冲击呢?是因为从不同控制台窗口运行的代码是在不同的处理器内核上执行的吗?如果是这样,我已经进行了大约20次这个实验,结果仍然是一样的.

Jon*_*eet 7

我打开两个控制台窗口并在第一个中执行java Hi.然后等待大约10秒钟,并在第二个窗口中执行相同操作.

你开始两个完全独立的过程.那根本就不使用多线程 - 每个进程都有自己的变量,自己的输出,一切.

要查看多线程,您需要在单个进程中创建线程.例如:

import java.util.Random;

class Counter implements Runnable {
    private int a;

    public void run() {
        Random random = new Random();
        for (int i = 0; i < 10; i++) {
            String name = Thread.currentThread().getName();
            a++;
            System.out.println(name + " Before sleep, a = " + a);
            try {
                // Add a little more uncertainty...
                Thread.sleep(random.nextInt(1000));
            } catch (InterruptedException e) {
                // Ignored
            }
            System.out.println(name + " After sleep, a = " + a);
        }
    }
}

public class ThreadingTest {
    public static void main(String[] args) throws InterruptedException {
        Counter counter = new Counter();
        Thread t1 = new Thread(counter);
        Thread t2 = new Thread(counter);
        t1.start();
        t2.start();
    }
}
Run Code Online (Sandbox Code Playgroud)

  • @Zapadlo请注意,Jon的例子只显示交错,因为`a`是公共对象中的实例字段,而不是`run`中的局部变量. (4认同)