| No. | Answer | Remark | |
|---|---|---|---|
| 1 | b c | Prints: 0 Prints: 1 | The new thread is started before the print statement, but there is no guarantee that the new thread will run before the print statement is processed. The guarantee could be provided by placing the method invocation expression a.join() before the print statement, but the invocation of the join method does not appear in the program. If the new thread runs before the print statement is processed, then 1 is printed. Otherwise, 0 is printed. |
| 2 | c | Prints: 1 | The a.run() method was called instead of a.start(); so the entire program runs as a single thread, and a.run() is guaranteed to complete before the print statement is called. |
| 3 | a c | Prints a number greater than or equal to 0 This program will run for at least ten seconds | Thread a1 will run for at least ten seconds, but the main method is likely to run to completion very quickly. The start method will return without waiting for thread a1 to complete. Since thread a1 immediately goes to sleep the thread that is processing the main method has an opportunity to complete the main method quickly. The number printed in the main method can be as small as zero. |
| 4 | e | volatile | A field might be shared between two or more threads. Each thread is allowed to maintain a working copy of the field. If the threads do not reconcile the working copies then each might be working with a different value. The volatile modifier is used to force each thread to reconcile its working copy of the field with the master copy in main memory. |
| 5 | a c | The first number printed is greater than or equal to 0 The second number printed must always be greater than 5000 | The notify method is never invoked on thread a1; so it will sleep for at least five seconds. The invocation of the join method forces the main thread to wait for the completion of thread a1. The argument of 6000 will allow the main thread to wait for six seconds if necessary, but we know that thread a1 will complete in only five seconds. The first number printed will be greater than or equal to zero, and the second number will be greater than or equal to 5000. The synchronized block is necessary, because it is necessary to hold the lock of an object when the wait method is invoked. |
| 6 | d | Prints: ABC |
The block inside the
main
method is synchronized on the
String
array object
sa.
Inside the block, a new thread
t1
is started and will run at the discretion of the
thread scheduler. The
|
| 7 | d | Prints: ABC |
Inside the
main
method, thread
t1
is started and will
move into the Running state at the discretion of the thread
scheduler. The
|
| 8 | b c d e h | The |
The
|
| 9 | b d | By entering a synchronized instance method of the obj1 By entering the body of a block that is synchronized on obj1 |
Blocking on I/O or invoking the
|
| 10 | a b d f | Another thread invokes the notify method on the object, obj1, and T1 is selected to move out of the wait set Another thread invokes the notifyAll method on the object Another thread interrupts thread T1 A specified timeout period has elapsed | |
| 11 | e | None of the above | All of the class instance creation expressions are legal. The String instance A is the name of the Thread. Yes, the exam requires you to memorize the Thread constructor signatures. |
| 12 | c | 3 | The position of the arguments have been reversed in the constructor on line 3. The Runnable argument should appear before the thread name argument. Yes, the exam requires you to memorize the Thread constructor signatures. |
| 13 | a | The number printed is greater than or equal to 0 | The notify method is never invoked on thread a1; so it will sleep forever and the program will not complete normally. |
| 14 | a | The number printed is greater than or equal to 0 | The a1 thread is a daemon thread; so the program can run to completion even if thread a1 is still running, waiting or sleeping. The notify method is never invoked on thread a1. If thread a1 were not a daemon thread, then the program would wait forever. However, the program will run to completion without waiting for a1. |
| 15 | b c | Some or all of the numbers 0 through 9 could be printed Nothing is printed |
All of the threads started in method
|
| 16 | e | Compile-time error |
Remember that the
|
| 17 | e | Compile-time error |
Remember that the
|
| 18 | d | Compile-time error |
Both the
sleep
and
join
methods declare an
InterruptedException
that must be caught or declared in the
throws
clause of
|
| 19 | e | An IllegalThreadStateException is thrown at run-time |
For the purposes of the exam,
invoking the start method on a
thread that has already been started will
generate an IllegalThreadStateException.
The actual behavior of Java might be different.
If the start method is invoked on a thread that is
already running, then an
IllegalThreadStateException will probably
be thrown. However, if the thread is already
dead then the second attempt to start the
thread will probably be ignored, and no
exception will be thrown. However, for the
purposes of the exam, the exception is
always thrown in response to the second invocation
of the start method.
This is a case where the exam
tests your knowledge of the specification of the
|
| 20 | b d | Prints: [T1,A][T2,B] Prints: [T2,B][T1,A] | Since method m1 is synchronized, it is guaranteed that no more than one thread will execute the method at any one time. Even though the start method is invoked on thread T1 first, there is no guarantee that it will actually begin to run first. |
| 21 | a | The priority assigned to thread T2 is greater than the priority assigned to T1 | The Java Language Specification suggests that higher priority threads should be given preference over lower priority threads, but explicitly states that the preference is not a guarantee. It is very important to remember that no guarantee exists. |