java并发问题

java并发问题,java,concurrency,Java,Concurrency,为什么n有时等于1或2 private static int n = 0; private static Thread t1, t2; private synchronized static void increment() { n++; } public static void main(String[] args) { t1 = new Thread(new Runnable() { public void run() { inc

为什么
n
有时等于1或2

private static int n = 0;

private static Thread t1, t2;

private synchronized static void increment() {
    n++;
}

public static void main(String[] args) {
    t1 = new Thread(new Runnable() {
        public void run() {
            increment();
        }
    });

    t2 = new Thread(new Runnable() {
        public void run() {
            t1.start();
            increment();
        }
    });

    t2.start();

    try {
        t2.join();
    } catch(InterruptedException e) {
        e.printStackTrace();
    }

    System.out.println(n);
}
增量方法不应该只允许一个线程在任何给定时刻执行它吗


可能是调试器,当我正常运行它时,似乎总是得到2,但当我调试代码时,它有时返回1。

是的,但它可能以任意顺序发生。您只等待
t2
完成,而不等待
t1
完成

同时等待
t1

private static int n = 0; 

private static Thread t1, t2;

private synchronized static void increment() {  // Lock will be on the "class" Object
    n++;
}

public static void main(String[] args) {
    t1 = new Thread(new Runnable() {
        public void run() {
            increment();
        }
    });

    t2 = new Thread(new Runnable() {
        public void run() {
            t1.start();           
// t1 starts after t2. Now, t1's increment might also be called or t2's increment() might also be called. If t2 calls increment(), then the join() method below (you are joining the in the main thread) will be completed and "n" will be printed (if t1 is not getting appropriate time of execution..)
            increment();
        }
    });

    t2.start();           // t2 starts first

    try {
        t2.join();
    } catch(InterruptedException e) {
        e.printStackTrace();
    }

    System.out.println(n); // increment() might not have been called by t1
}

不能保证一个线程会在另一个线程之前执行(即使在同步条件下…)。因此,您可以在t1和t2上加入
join
。这将确保您始终以2的形式获得输出。

我想如果
t2
run
方法中的
increment
调用发生在
t1
run
方法中调用
increment
方法之前,然后,
n
被锁定,在
t2
结束时,
t1
可能仍在运行,但在
t1
的增量结束之前,您正在打印出
n
增量为
t2

澄清:

  • t2
    开始
  • t2
    生成
    t1
  • t2
    t1
    有机会
  • n
    t2
    增量期间被锁定
  • 线程
    t1
    之前加入
    t2
    有机会
    增量
  • main
    Thread
    t1
    有机会
    递增之前打印
    n

看起来,因为您有静态线程实例,我建议您停止将所有内容设置为静态。另外,不要调用
t1.start()t2
run方法中的code>。@ElliottFrisch-静态
线程实例会有什么影响?。即使线程实例不是静态的,他仍然会以同样不可预测的行为结束。对吗?@最重要的是,不仅仅是静态线程实例,我观察到所有的东西都是静态的。还有,为什么会有呢?这就是为什么不在
main
方法中声明它们呢?@ElliottFrisch-Oh。。好的……)