【发布时间】:2013-07-09 08:13:28
【问题描述】:
我一直在努力为下周必须参加的 SCJP 考试做准备,我遇到了这个关于 Java 线程 的问题。
1-public class Stone implements Runnable {
2- static int id = 1;
3-
4- public void run() {
5- try {
6- id = 1 - id;
7- if (id == 0) {
8- pick();
9- } else {
10- release();
11- }
12-
13- } catch (Exception e) {
14- }
15- }
16-
17- private static synchronized void pick() throws Exception {
18- System.out.print("P ");
19- System.out.print("Q ");
20- }
21-
22- private synchronized void release() throws Exception {
23- System.out.print("R ");
24- System.out.print("S ");
25- }
26-
27- public static void main(String[] args) {
28- Stone st = new Stone();
29- new Thread(st).start();
30- new Thread(st).start();
31- }
32-}
- 哪些是真的? (选择所有适用的选项。)
- 输出可能是 P Q R S
- 输出可能是 P R S Q
- 输出可能是 P R Q S
- 输出可能是 P Q P Q
- 该程序可能会导致死锁。
- 编译失败。
答案是:
A、B 和 C 是正确的。由于 pick() 是静态的,而 release() 是非静态的,所以
是两把锁。如果 pick() 是非静态的,那么只有 A 是正确的。
它还说输出 P Q P Q 不是一个真正的选项,不可能得到这样的结果。
一开始,我并不真的相信答案,但后来我发现,这个应用程序的结果真的不可能看到这个输出。 (上课后。)
现在,这就是让我有点困惑的部分,这就是原因
我认为 P Q P Q 或 R S R S 结果一定是可能的。因为总是有机会使两个线程的变量 id 完全相同。换句话说,例如,当第一个线程刚刚执行完第 6 行时,它可以放弃轮到另一个线程,之后,另一个线程可以更改变量 id 的值,然后瞧!如果愉快地阻塞,他们可以进入相同的状态。
我一遍又一遍地尝试看到这种情况(使用 Eclipse Juno 和 Java 7)。它只是不会发生。我确信我的思维方式有问题,我想知道它是什么。 我需要知道阻止这两个线程访问处于相同状态的变量 id 的规则是什么。
【问题讨论】:
-
R S R S 绝对不可能,因为如果 id==0 会触发“R S”,它肯定不会自行到达那里。不过,“P Q P Q”对我来说似乎是可能的——两个线程都看到 id==1(run() 没有同步),都调用 pick() ....
-
R S R S 在它们都运行时是可能的,将 id 递减为 -1 然后输入条件。但极不可能,因为第一个线程必须在递减后中断。
-
PQPQ 是不可能的,因为只有一个线程可以到达第 7 行的 if 语句,id 值为 0。原因是两个线程必须通过第 6 行,因此,如果留下一个线程,到达第 7 行时它的值为 -1。如果两个线程一起移动,那么到达第 7 行时它们的 id 值为 -1。
-
@Tsikon - 不。不要仅仅因为您将其视为 java 的一行而认为它是原子的。您可以将“id = 1 - id”视为“int temp = id-1; id=temp;”。
-
@Tsikon 你是如何真正找到
1-id! 的 -1 值的?你怎么确定只有一个线程在第 7 行?
标签: java multithreading concurrency static