奇怪的java并发行为

奇怪的java并发行为,java,concurrency,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

我有以下代码:

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);
      }
   }
}
没有交错。所以,如果我甚至懒得使用synchronized语句,那么并发性问题会引起什么骚动呢?是因为从不同控制台窗口运行的代码在不同的处理器内核上执行吗?如果是这样的话,我已经做了20次这个实验,结果还是一样的

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

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


是的,如果同一JVM中有两个线程,则并发性适用。

这是计算机上两个独立的进程。他们不共享数据或其他任何东西。它们不再相关,例如,您的web浏览器和文字处理器。它们都有各自独立的变量,彼此完全无关


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

因为在这里您正在运行两个不同的进程,无论您运行此代码多少次,都会得到相同的结果。因为这两个程序都将在两个单独的进程中运行


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

我不明白。您希望发生什么?那么您正在运行两个不同的程序?请注意,即使您有多个线程,局部变量通常也不会共享。如果启动两个线程,并且两个线程都调用一个mainProcess方法,并且该方法有一个局部变量,如示例中的a,则每个方法仍将有该变量的副本,并且不会出现并发问题。@ajb:尽管如果两个变量引用同一对象,您仍然可以共享。但与int等原语无关。这两个原语位于不同的JVM中,开始注意到您无处不在:P@Zapadlo请注意,Jon的示例将显示交错,因为a是公共对象中的实例字段,而不是运行中的局部变量。
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();
    }
}