0

谁能解释这段代码:

public class Main implements Runnable{

private int i;
public synchronized void run() {
    System.out.print("i = "+ i +"\n");
    if (i % 5 != 0) {
        i++;
    }
    for (int x = 0; x < 5; x++, i++) {
        if (x > 1) {
            Thread.yield();
        }
    }
}

 public static void main(String[] args) {
    Main n = new Main();
    for (int x = 100; x > 0; --x) {
        new Thread(n).start();
    }
}
}

以及输出如何

i= 0
i= 5
i= 10
i= 15
i= 20
.
.
.
i= 499
4

3 回答 3

3

底部循环创建 100 个线程。每个线程都立即运行,与其他线程并行运行。在每个线程中,

  • 在开始时,打印共享属性“i”的当前值
  • 如果 i 不能被 5 整除,则递增一次
  • 然后执行一个循环,最多 5 次。它执行的最后 3 次,它让给其他线程。每次执行此循环时,它都会增加共享变量“i”

因此,如果 i 能被 5 整除,则 i 增加 5 倍,否则增加 6 倍。但是, run() 方法是同步的。因此,当其中一个线程已经在执行时,不允许其他线程执行:您的程序实际上是单线程的,yield() 被忽略(没有其他线程可以执行),并且输出与

for (int i=0; i<500; i+= 5) System.out.println(i);
System.out.println(499);

删除 synchronized 以查看改变输出的各种竞争条件。

于 2013-01-12T12:51:42.613 回答
2

主线程创建 100 个线程,每个线程执行一个同步方法,以便它们序列化执行。每个线程都打印 i 的当前值(开始时默认为 0)并将其递增 5 次,以便下一个要占用 cpu(并执行主体)的线程打印 的新值i

Thread.yield(); 放弃 CPU 但并不意味着它会释放锁。这就是为什么每个线程run在前一个线程完成后才执行方法而不是其他的原因。

于 2013-01-12T12:41:09.413 回答
1

重要的是要了解yield不释放监视器。因此,您的所有线程都按顺序运行,即yield不允许其他线程运行,因为它在一个synchronized块内并且监视器保持锁定状态。

于 2013-01-12T12:52:55.247 回答