Page: 10
9. Multi-Threading
41. Given the following:
class MyThread extends Thread {
MyThread() {
System.out.print(" MyThread");
}
public void run() { System.out.print(" bar"); }
public void run(String s) { System.out.print(" baz"); }
}
public class TestThreads {
public static void main (String [] args) {
Thread t = new MyThread() {
public void run() { System.out.print(" foo"); }
};
t.start();
} }
What is the result?
A. foo
B. MyThread foo
C. MyThread bar
D. foo bar
E. foo bar baz
F. bar foo
G. Compilation fails.
H. An exception is thrown at runtime.
Answer:
-> B is correct. The first line of main we're constructing an instance of an anonymous innerclass extending from MyThread. So the MyThread constructor runs and prints MyThread. Next, main() invokes start() on the new thread instance, which causes the overridden run() method (the run() method in the anonymous inner class) to be invoked.
-> A, C, D, E, F, G and H are incorrect based on the logic described above.
42. Given
public class ThreadDemo {
synchronized void a() { actBusy(); }
static synchronized void b() { actBusy(); }
static void actBusy() {
try { Thread.sleep(1000); }
catch (InterruptedException e) {}
}
public static void main(String[] args) {
final ThreadDemo x = new ThreadDemo();
final ThreadDemo y = new ThreadDemo();
Runnable runnable = new Runnable() {
public void run() {
int option = (int) (Math.random() * 4);
switch (option) {
case 0: x.a(); break;
case 1: x.b(); break;
case 2: y.a(); break;
case 3: y.b(); break;
} }
};
Thread thread1 = new Thread(runnable);
Thread thread2 = new Thread(runnable);
thread1.start();
thread2.start();
} }
Which of the following pairs of method invocations could NEVER be executing at the same
time? (Choose all that apply.)
A. x.a() in thread1, and x.a() in thread2
B. x.a() in thread1, and x.b() in thread2
C. x.a() in thread1, and y.a() in thread2
D. x.a() in thread1, and y.b() in thread2
E. x.b() in thread1, and x.a() in thread2
F. x.b() in thread1, and x.b() in thread2
G. x.b() in thread1, and y.a() in thread2
H. x.b() in thread1, and y.b() in thread2
Answer:
-> A , F and H. A is incorrect because synchronized instance methods called on the same instance, block each other. F and H could not happen because synchronized static methods in the same class block each other, regardless of which instance was used to call the methods. (An instance is not required to call static methods; only the class.)
-> C could happen because synchronized instance methods called on different instances do not block each other. B, D, E, and G could all happen because instance methods and static methods lock on different objects, and do not block each other. (Objective 4.3)
43. Given the following,
1. public class Test {
2. public static void main (String [] args) {
3. final Foo f = new Foo();
4. Thread t = new Thread(new Runnable() {
5. public void run() {
6. f.doStuff();
7. }
8. });
9. Thread g = new Thread() {
10. public void run() {
11. f.doStuff();
12. }
13. };
14. t.start();
15. g.start();
16. }
17. }
1. class Foo {
2. int x = 5;
3. public void doStuff() {
4. if (x < 10) {
5. // nothing to do
6. try {
7. wait();
8. } catch(InterruptedException ex) { }
9. } else {
10. System.out.println("x is " + x++);
11. if (x >= 10) {
12. notify();
13. }
14. }
15. }
16. }
What is the result?
A. The code will not compile because of an error on line 12 of class Foo.
B. The code will not compile because of an error on line 7 of class Foo.
C. The code will not compile because of an error on line 4 of class Test.
D. The code will not compile because of some other error in class Test.
E. An exception occurs at runtime.
F. x is 5
x is 6
Answer:
-> E is correct because the thread does not own the lock of the object it invokes wait() on.
If the method were synchronized, the code would run without exception.
-> A, B, C, and D are incorrect because the code compiles without errors. F is incorrect
because the exception is thrown before there is any output. (Objective 4.4)
44. Given:
public class TwoThreads {
static Thread laurel, hardy;
public static void main(String[] args) {
laurel = new Thread() {
public void run() {
System.out.println("A");
try {
hardy.sleep(1000);
} catch (Exception e) {
System.out.println("B");
}
System.out.println("C");
}
};
hardy = new Thread() {
public void run() {
System.out.println("D");
try {
laurel.wait();
} catch (Exception e) {
System.out.println("E");
}
System.out.println("F");
}
};
laurel.start();
hardy.start();
}
}
Which letters will eventually appear somewhere in the output? (Choose all that apply.)
A. A B. B
C. C D. D
E. E F. F
G. The answer cannot be reliably determined.
H. The code does not compile.
Answer:
-> A , C, D, E and F are correct. This may look like laurel and hardy are battling to cause the other to sleep() or wait()—but that's not the case. Since sleep() is a static method, it affects the current thread, which is laurel (even though the method is invoked using a reference to hardy). That's misleading but perfectly legal, and the Thread laurel is able to sleep with no exception, printing A and C (after a 1-second delay). Meanwhile hardy tries to call laurel.wait()—but hardy has not synchronized on laurel, so calling laurel.wait() immediately causes an IllegalThreadStateException, and so hardy prints D, E, and F. Although the order of the output is somewhat indeterminate (we have no way of knowing whether A is printed before D, for example) it is guaranteed that A, C, D, E, and F will all be printed in some order, eventually—so G is incorrect.
-> B, G and H are incorrect based on the above
Page: 10
1
2
3
4
5
6
7
8
9
10