奇怪的java并发行为

时间:2014-11-25 17:57:16

标签: 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);
      }
   }
}

我打开两个控制台窗口并在第一个窗口中执行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

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

4 个答案:

答案 0 :(得分: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();
    }
}

答案 1 :(得分:4)

你有两个不同的JVM,所以在两个不同的JVM上运行两个主线程,所以并发不适用。

如果在同一个JVM中有两个线程,则应用并发。

答案 2 :(得分:3)

这些是您计算机上的两个独立进程。他们不共享数据或其他任何东西。它们不再相关,例如,您的Web浏览器和您的文字处理器。他们每个人都有自己独立的&#34; a&#34;变量,每个都与另一个完全无关。

当同一进程空间中的多个线程尝试访问同一个变量时,就会出现并发问题。这不适用于此。

答案 3 :(得分:1)

在这里,您运行两个不同的进程,无论您运行此代码多少次,您都将获得相同的结果。由于这两个程序都将在两个独立的进程中运行。

要以多线程方式运行这些程序,您必须实现两个线程并启动它们。