public class SyncTest {
public static void main(String[] args) {
final StringBuffer s1 = new StringBuffer();
final StringBuffer s2 = new StringBuffer();
new Thread() {
public void run() {
synchronized (s1) {
s2.append("A");
synchronized (s2) {
s2.append("B");
System.out.print(s1);
System.out.print(s2);
}
}
}
}.start(); new Thread() {
public void run() {
synchronized (s2) {
s2.append("C");
synchronized (s1) {
s1.append("D");
System.out.print(s2);
System.out.print(s1);
}
}
}
}.start();
}
}
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.
请问选哪2个,为什么?
public static void main(String[] args) {
final StringBuffer s1 = new StringBuffer();
final StringBuffer s2 = new StringBuffer();
new Thread() {
public void run() {
synchronized (s1) {
s2.append("A");
synchronized (s2) {
s2.append("B");
System.out.print(s1);
System.out.print(s2);
}
}
}
}.start(); new Thread() {
public void run() {
synchronized (s2) {
s2.append("C");
synchronized (s1) {
s1.append("D");
System.out.print(s2);
System.out.print(s1);
}
}
}
}.start();
}
}
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.
请问选哪2个,为什么?
线程start只是告诉系统线程准备好了.具体什么时候启动执行run要看系统的线程模型,有可能线程1先启动,也有可能线程2先启动.线程切换的时机也是不确定的.
假设当一个线程在s1和s2两个同步语句中间切换到另一个线程并进入同步块的话,此时线程1因为s2被线程2锁住,取不到s2锁.线程2因为s1被线程1锁住,取不到s1的锁,因而造成死锁.
两种情况是ABABCD和CDDCAB
两个线程启动,但并不是如程序上的顺序启动,有可能是线程1先开始,也有可能是线程2.
因为加了synchronized 的关系,执行过程不会从一个线程切换到另一个,除非执行完同步区域的代码.
所以,两种步骤为:
1.线程1先动,s2.append("A");s2.append("B");System.out.print(s1);System.out.print(s2);
此时结果为AB(只有s2有值,s1没有),然后执行线程2的程序,s2.append("C");s1.append("D");System.out.print(s2);System.out.print(s1);加上之前的结果为ABABCD,s1的值为D,s2的值为ABC2.线程2启动,s2.append("C");s1.append("D");System.out.print(s2);System.out.print(s1);
此时结果为CD,s1为D,s2为C,再启动线程1,s2.append("A");s2.append("B");System.out.print(s1);System.out.print(s2);结果为CDDCAB,s1为D,s2为CAB
public static void main(String[] args) {
final StringBuffer s1 = new StringBuffer();
final StringBuffer s2 = new StringBuffer();
new Thread() {
public void run() {
synchronized (s1) {
s2.append("A");
try{
Thread.sleep(10);
}catch(Exception e){e.printStackTrace();}
synchronized (s2) {
s2.append("B");
System.out.print(s1);
System.out.print(s2);
}
}
}
}.start(); new Thread() {
public void run() {
synchronized (s2) {
s2.append("C");
try{
Thread.sleep(10);
}catch(Exception e){e.printStackTrace();}
synchronized (s1) {
s1.append("D");
System.out.print(s2);
System.out.print(s1);
}
}
}
}.start();
}
答案应该是DE,如1楼所说,可能会死锁。用上面的代码可以验证
我测试了 出现了啊 ABABCD 为什么会出现这种现象
若将程序中的 print 改成 println 就看看到下面的请况(空行)// 第一个System.out.print(s1)
AB // 第一个System.out.print(s2); s2扩充了A,B
ABC // 第二个System.out.print(s2); s2又扩充了C
D // 第二个System.out.print(s1); s1扩充了D说明了我的电脑 是第一个线程把 s1,s2都锁定了 第二个线程才启动的
这说明了 E 是对的 和我的电脑结合很紧若电脑启动第二个线程快 就会死锁 我的电脑通过sleep模仿class SyncTest {
public static void test() {
final StringBuffer s1 = new StringBuffer();
final StringBuffer s2 = new StringBuffer();
new Thread() {
public void run() {
synchronized (s1) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
s2.append("A");
synchronized (s2) {
s2.append("B");
System.out.println(s1);
System.out.println(s2);
}
}
}
}.start(); new Thread() {
public void run() {
synchronized (s2) {
s2.append("C");
synchronized (s1) {
s1.append("D");
System.out.println(s2);
System.out.println(s1);
}
}
}
}.start();
}
}这样就死锁了 互相先要对方已经锁定了的锁 】
说明 D是对的