琢磨不透的一道题.

wisjeremy 2008-07-13 04:20:35

import java.util.*;

public class NameList {
private List names = new ArrayList();
public synchronized void add(String name) { names.add(name); }
public synchronized void printAll() {
for (int i = 0; i <names.size(); i++) {
System.out.print(names.get(i) +“ “);
}
}
public static void main(String[] args) {
final NameList sl = new NameList();
for(int i=0;i<2;i++) {
new Thread() {
public void ruin() {
sl.add(”A”);
sl.add(”B”);
sl.add(”C”);
sl.printAll();
}
}.start();
}
}
}

Which two statements are true if this class is compiled and run?(Choose two.)
A. An exception may be thrown at runtime.
B. The code may run with no output, without exiting.
C. The code may run with no output, exiting normally.
D. The code may rum with output “A B A B C C “, then exit.
E. The code may rum with output “A B C A B C A B C “, then exit.
F. The code may ruin with output “A A A B C A B C C “, then exit.
G. The code may ruin with output “A B C A A B C A B C “, then exit.
Answer: EG

答案为什么会是EG?!
我觉得是AD.
final NameList sl = new NameList(); //这句当中的final对题目有什么影响吗?
...全文
260 24 打赏 收藏 转发到动态 举报
写回复
用AI写文章
24 条回复
切换为时间正序
请发表友善的回复…
发表回复
new_bird_0001 2008-07-15
  • 打赏
  • 举报
回复
交叉打印至少9个字母,可排除D,三个A不可能连续打印出来,可排除F,E是最简单的可能性,G推敲一下完全可能.
ryan0629 2008-07-15
  • 打赏
  • 举报
回复
首先List name里面的值最后是ABCABC
线程一add完之后,开始打印,线程2开始add
由于printAll也是同步的,所以开始打印出来的,肯定是线程一打印的,所以打印的前三个肯定是ABC
那么线程一还能不能再打印,就要看线程一打印完ABC后,线程二往name里面add了几个了,所以结果应该有如下几种
ABC ABCABC
ABCA ABCABC
ABCAB ABCABC
ABCABC ABCABC
前一段是线程一打印,后一段为线程二打印
hemaily 2008-07-15
  • 打赏
  • 举报
回复
由于printAll方法被锁,那么2个线程是按照先后顺序打印。所以后执行的线程打印的字母数一定为6个。
先打印的线程字母数为3-6个。
可能的结果为:
ABC ABCABC
AABC AABCBC
ABAC ABACBC
ABCA ABCABC
AABBC AABBCC
AABCB AABCBC
ABABC ABABCC
ABACB ABACBC
ABCAB ABCABC
AABBCC AABBCC
ABABCC ABABCC
ABACBC ABACBC
ABCABC ABCABC

学习一下
alex0058 2008-07-15
  • 打赏
  • 举报
回复
还是楼上的对,我的分析有误:后打印的不一定是“ABCABC”
duhongltz 2008-07-15
  • 打赏
  • 举报
回复
由于printAll方法被锁,那么2个线程是按照先后顺序打印。所以后执行的线程打印的字母数一定为6个。
先打印的线程字母数为3-6个。
可能的结果为:
ABC ABCABC
AABC AABCBC
ABAC ABACBC
ABCA ABCABC
AABBC AABBCC
AABCB AABCBC
ABABC ABABCC
ABACB ABACBC
ABCAB ABCABC
AABBCC AABBCC
ABABCC ABABCC
ABACBC ABACBC
ABCABC ABCABC
alex0058 2008-07-15
  • 打赏
  • 举报
回复
首先,死锁的状态不会出现,所以两个线程都能正常结束,a、b和c错。
然后其实就是一个排列组合的问题了,两个线程互斥访问对象sl。
要注意的是print的时候数组里有几个字符,注意到这一点后,事实上也d很容易排除掉。因为最后执行的printAll就会打印六个字符,如果在思考一下,就会发现这六个字符坑定是“ABCABC”,故f也错。至于可能的结果,20楼的分析的很清楚了。
a65096060 2008-07-13
  • 打赏
  • 举报
回复
初学者,看不懂,哪位高手能详细解释下
daybybyby 2008-07-13
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 daybybyby 的回复:]
如果public void ruin() = public void run()的话 ,ABCD肯定都不对了,
只有两个线程,完全按照一个执行完执行另一个的顺运行才会有6个字母,顺序ABCABC. so d is wrong,
同样的, f中一开始三个A是不对的.两个线程怎么交叉执行也不会出来三个A一起的.

[/Quote]

不好意思, 学艺不精
“只有两个线程,完全按照一个执行完执行另一个的顺运行才会有6个字母,顺序ABCABC. so d is wrong”

这句话说错了,两个线程执行,无论如何交叉执行,打印字母数都至少大于6个。
最少该9个吧?这个我没仔细想
happy08_xhx 2008-07-13
  • 打赏
  • 举报
回复
线程的不太懂,mark一个
daybybyby 2008-07-13
  • 打赏
  • 举报
回复
g的过程:

-->线程1
A进list B进list C进list
-->切换至线程2
A进list
-->切换至线程1
printall 打印 ABCA
线程1结束
-->切换至线程2
B进list C 进list printall ABCABC
结果 ABCAABCABC

wisjeremy 2008-07-13
  • 打赏
  • 举报
回复
9958!! - -
youzy 2008-07-13
  • 打赏
  • 举报
回复
厉害,还是不要琢磨了,高深!
dayou123123 2008-07-13
  • 打赏
  • 举报
回复
怪哉
wisjeremy 2008-07-13
  • 打赏
  • 举报
回复
对印刷错误..ruin是run
粘贴的时候忘记改过来了
E是懂了
可是G还是迷糊...
jdlsfl 2008-07-13
  • 打赏
  • 举报
回复
关注
应该是run
daybybyby 2008-07-13
  • 打赏
  • 举报
回复
如果public void ruin() = public void run()的话 ,ABCD肯定都不对了,
只有两个线程,完全按照一个执行完执行另一个的顺运行才会有6个字母,顺序ABCABC. so d is wrong,
同样的, f中一开始三个A是不对的.两个线程怎么交叉执行也不会出来三个A一起的.
ZangXT 2008-07-13
  • 打赏
  • 举报
回复
如果是run的话G也是可能的.
sl.add(”A”);
sl.add(”B”);
sl.add(”C”);
add方法是同步的,但是两个线程执行这三句的过程可能是交叉的.自己分析一下具体情况就可以了.
从答案来看,题目中ruin是印刷错误吧.
ZangXT 2008-07-13
  • 打赏
  • 举报
回复
题目有问题吧 public void ruin()是不是要写run()
要不有什么意思
ZangXT 2008-07-13
  • 打赏
  • 举报
回复
我感觉E肯定是正确的.
因为一共创建了两个线程,第一个往sl,加入了ABC,所以输出ABC
第二个线程又加入了ABC ,所以现在sl中的names一共有六个元素,输出ABCABC.
所以E没有问题.
  • 打赏
  • 举报
回复
A B C A B C A B C
A A B B C C A A B B C C
就这两种结果。牛人来解释下啊。。不懂。
加载更多回复(3)

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧