几个有争议的关于thread的题(转自javaren的一篇讨论)

发表于:2007-07-04来源:作者:点击数: 标签:
formyjoy 最近做了几套题,也在网上参与了大家的讨论,但发现有几个题大家有些争议,现重贴如下,希望大家指正 Q1 1. public class SyncTest{****** 2. public static void main(String[] args) { 3. final StringBuffer s1= new StringBuffer(); 4. final String
formyjoy
最近做了几套题,也在网上参与了大家的讨论,但发现有几个题大家有些争议,现重贴如下,希望大家指正
Q1
1. public class SyncTest{         ******
2. public static void main(String[] args) {
3. final StringBuffer s1= new StringBuffer();
4. final StringBuffer s2= new StringBuffer();
5. new Thread () {
6. public void run() {
7. synchronized(s1) {
8. s1.append("A");
9. synchronized(s2) {
10. s2.append("B");
11. System.out.print(s1);
12. System.out.print(s2);
13. }
14. }
15. }
16. }.start();
17. new Thread() {
18. public void run() {
19. synchronized(s2) {
20. s2.append("C");
21. synchronized(s1) {
22. s1.append("D");
23. System.out.print(s2);
24. System.out.print(s1);
25. }
26. }
27. }
28. }.start();
29. }
30. }
Which two statements are true? (Choose Two)
A. The program prints "ABBCAD"
B. The program prints "CDDACB"
C. The program prints "ADCBADBC"
D. The output is a non-deterministic point because of a possible deadlock condition
E. The output is dependent on the threading model of the system the program is running on.
我分析了一下,觉得有可能发生deadlock(D),另外我编译运行了一下,结果为CDDACB(B),
谁能具体分析一下这道题中线程执行的过程.

Q2
class s implements Runnable{
int x=0,y=0;
synchronized void addX(){x++; }
synchronized void addY(){y++; }
void addXY(){x++;y++;}
boolean check() { return (x>y)? true:false;)
public void run() {
// ?
System.out.println(check()); }
public static void main(String args[])
{ s run=new s();
Thread t1=new Thread(run);
Thread t2=new Thread(run);
t1.start();
t2.start();
}
}
If this methods are called in which order the check will return true?
Select all that apply
A.call addX() and addY() simultaneously for number of times in run()
B.call addY() and addX() simultaneously for number of times in run()
C.all addXY() for number of times in run()
Ans:B,C
C没有问题,B?A,为何B也正确,而且是先访问addY();
I think in all cases, check() can return true.
because addX() and addY() are synchronized but run is not synchronized,
hence it is very much possible that after calling addX() another thread
starts execution and increment the x again and then check() will return
true(This explanation is true for first two cases).
For third case as it(addXY()) is not synchronized so any thread can corrupt
the data, and check() can return true.

Q3
class Happy extends Thread {
final StringBuffer sb1 = new StringBuffer();
final StringBuffer sb2 = new StringBuffer();
public static void main(String args[]) {
final Happy h=new Happy();
System.out.println(h);
new Thread() {
public void run(){
System.out.println(this);
synchronized(this) {
h.sb1.append("A");
h.sb2.append("B");
System.out.println(h.sb1);
System.out.println(h.sb2);
}
}
}.start();
new Thread() {
public void run() {
System.out.println(this);
synchronized(this) {
h.sb1.append("D");
h.sb2.append("C");
System.out.println(h.sb2);
System.out.println(h.sb1);
}
}
}.start();   
}
}
What may be the output of this code ?(Choose two)
a) ABBCAD
b) ABCBCAD
c) CDADACB
d) CDDACB
e) Output non-deterministic because of the chance of deadlock?
f) Output determined due to the underlying platFORM.
这道题与Q1有类似之处,但好像实际上不一样,希望各位大虾加以讨论.
-------------------------------
ericsun
关于问题3 -- 在 "一道线程题" 中出现过。 下面是我当时的回答。

to cqing & stonely      
I agree with you. From logical judgement, a, b, c, d are all can be happened.
But in compile time or run time, perhaps which thread.start write first should
be start first at first one sentence. So if really need to choose two question,
I select a and b.
If the question change like ::

public void run(){
System.out.println(this);

// i add some waste thing.
for ( int i=0;i<300;i++) { int j=0; j=i; }

synchronized(this) {

h.sb1.append("A");

h.sb2.append("B");

System.out.println(h.sb1);

System.out.println(h.sb2);

}

The question''s answer perhaps will be a,b,c,d.
-------------------------------------------------------------
cqing
一点不同意见,没有人能够保证which thread.start write first start first,
因为JVM控制不了何时thread投入运行,这和具体的系统有关。thread.start仅仅是通知操作系统
我有一个thread要运行,至于何时运行,由操作系统决定。不过做题嘛,看出题人怎么考虑了,
如果你的思路和他一样,也许就对了,不一样,也许就错了。这里的6个答案,确定错误的只有E,
其他的,实在是不知道。
-------------------------------------------------------------
ericsun
Q1 的分析如下:
这里显然有个死锁的可能。选 D .
然后排除死锁的情况。
原题等同与

new Thread () {
6. public void run() {
7. synchronized(s1,s2) { // 形式话语言。
8. s1.append("A");
10. s2.append("B");
11. System.out.print(s1);
12. System.out.print(s2);
13. }
15. }
16. }.start();

另一个 Thread 相同,就是说同时锁住两个变量了 s1, s2 .

那问题就简单了。

1。如果第一个先运行的话.
s1="A", s2="B"  println s1s2 = AB
接下来,
s2="BC", s1="AD" println s2s1=BCAD

结果是 ABBCAD


2。如果第二个先运行的话.
s2="C", s1="D" println s2s1=CD
接下来,
s1="DA", s2="CB"  println s1s2 =DACB

结果是 CDDACB

所以答案是 A.B

看来有三个答案一定对 A B D.
如果一定要选两个, 那就要选 D E(包含了A,B) 了。
或是 A B 了 排除 死锁的情况。

对不对呢 cqing.顺便问一下,不同的 system 会有不同的 thread model 对不对啊。
---------------------------------------------------
ericsun
Q2 的答案是 A C . 原来的 答案错了。
你可以这样试一下:
synchronized void addX(){
x++;
try{Thread.sleep(100); }catch(Exception e){}
}
synchronized void addY(){
y++;
try{Thread.sleep(100); }catch(Exception e){}
}

然后 in run() addX() , addY() or addY() addX()

就可以证实你的想法了。
-------------------------------------------------
cqing      

  Q1我考试的时候做过,可以肯定答案是D E.
Q2我以前贴过一个在javaranch上的地址,那里有很多超级高手,可是好像也没有定论,
我个人倾向于A C
ericsun,你说得没错, 不同的 system 会有不同的 thread model
--------------------------------------------------
hongwgjy      
解说一下怎样形成死锁
--------------------------------------------------
formyjoy
  比如Q1说第一个线程运行得到s1的lock,这是第二个线程得到了s2的lock,
  那么第一个线程必须等待第二个线程释放s2的lock才能继续运行,而这时
  第二个线程却无法运行下去(因为s1的lock还被别人占着)。这样deadlock就形成了。
这几个题大家理解一下,考试很可能考到的。 

原文转自:http://www.ltesting.net