10 - Java 8 OCP - Threads
Given: class A { static long flag = 0; //INSERT CODE HERE if(flag == 0)flag = id; for(int x = 1; x < 3; x++){ if(flag == id)System.out.print("Yo "); else System.out.print("dude "); }}} public class B implements Runnable{ static A d; public static void main(String[] args) { new B().go(); } void go() { d = new A(); new Thread(new B()).start(); new Thread(new B()).start(); } public void run() { d.chat(Thread.currentThread().getId()); }} And given these two fragments: I. synchronized void chat(long id) { II. void chat(long id) { When fragment I or fragment II is inserted above, which are true? (Choose all that apply.) A. An exception is thrown at runtime B. With fragment I, compilation fails C. With fragment II, compilation fails D. With fragment I, the output could be yo dude dude yo E. With fragment I, the output could be dude dude yo yo F. With fragment II, the output could be yo dude dude yo
F is correct. With fragment II, the output could be "yo dude dude yo" With Fragment I, the chat method is synchronized, so the two threads cannot swap back and forth. With either fragment, the first output must be "yo". Let's step through the code with fragment I: ===Code Step Through=== 1: class A { 2: static long flag = 0; 3: synchronized void chat(long id) { 4: if(flag == 0)flag = id; 5: for(int x = 1; x < 3; x++){ 6: if(flag == id)System.out.print("Yo "); 7: else System.out.print("dude "); 8: }}} 9: public class B implements Runnable{ 10: static A d; 11: public static void main(String[] args) { 12: new B().go(); 13:} 14: void go() { 15: d = new A(); 16: new Thread(new B()).start(); 17: new Thread(new B()).start(); 18: } 19: public void run() { 20: d.chat(Thread.currentThread().getId()); 21: }} On the line 12, a new B object instance is created and its method go() is called. ========2======== 1: class A { 2: static long flag = 0; 3: synchronized void chat(long id) { 4: if(flag == 0)flag = id; 5: for(int x = 1; x < 3; x++){ 6: if(flag == id)System.out.print("Yo "); 7: else System.out.print("dude "); 8: }}} 9: public class B implements Runnable{ 10: static A d; 11: public static void main(String[] args) { 12: new B().go(); 13:} 14: void go() { 15: d = new A(); 16: new Thread(new B()).start(); 17: new Thread(new B()).start(); 18: } 19: public void run() { 20: d.chat(Thread.currentThread().getId()); 21: }} On the line 14, the go() method block is entered and a new object instance of tight A is created with static reference d. ========3======== 1: class A { 2: static long flag = 0; 3: synchronized void chat(long id) { 4: if(flag == 0)flag = id; 5: for(int x = 1; x < 3; x++){ 6: if(flag == id)System.out.print("Yo "); 7: else System.out.print("dude "); 8: }}} 9: public class B implements Runnable{ 10: static A d; 11: public static void main(String[] args) { 12: new B().go(); 13:} 14: void go() { 15: d = new A(); 16: new Thread(new B()).start(); 17: new Thread(new B()).start(); 18: } 19: public void run() { 20: d.chat(Thread.currentThread().getId()); 21: }} On the line 16 and 17, within the go() method block, two new threads are created (in sequence) containing the class B which implements runnable. These threads are started using the start() method, which implicitly call the run() method on the line 19. The threads are is placed in the "Runnable" state by the JVM scheduler and at the time of JVMs choosing, it will place the thread in the running state. ========4======== 1: class A { 2: static long flag = 0; 3: synchronized void chat(long id) { 4: if(flag == 0)flag = id; 5: for(int x = 1; x < 3; x++){ 6: if(flag == id)System.out.print("Yo "); 7: else System.out.print("dude "); 8: }}} 9: public class B implements Runnable{ 10: static A d; 11: public static void main(String[] args) { 12: new B().go(); 13:} 14: void go() { 15: d = new A(); 16: new Thread(new B()).start(); 17: new Thread(new B()).start(); 18: } 19: public void run() { 20: d.chat(Thread.currentThread().getId()); 21: }} For the purposes of this example, let's assume that the first thread entering the running state is online 16. On the line 19, the run() method is implicitly called from the thread created and started on the line 16. ========5======== 1: class A { 2: static long flag = 0; 3: synchronized void chat(long id) { 4: if(flag == 0)flag = id; 5: for(int x = 1; x < 3; x++){ 6: if(flag == id)System.out.print("Yo "); 7: else System.out.print("dude "); 8: }}} 9: public class B implements Runnable{ 10: static A d; 11: public static void main(String[] args) { 12: new B().go(); 13:} 14: void go() { 15: d = new A(); 16: new Thread(new B()).start(); 17: new Thread(new B()).start(); 18: } 19: public void run() { 20: d.chat(Thread.currentThread().getId()); 21: }} On the line 20, within the run method, a call is made to the chat() method of the class A with reference d. Within the parameters of this method, the current thread ID is passed. As this is an arbitrary number, we will let this number equal to 2. ========6======== 1: class A { 2: static long flag = 0; 3: synchronized void chat(long id) { 4: if(flag == 0)flag = id; 5: for(int x = 1; x < 3; x++){ 6: if(flag == id)System.out.print("Yo "); 7: else System.out.print("dude "); 8: }}} 9: public class B implements Runnable{ 10: static A d; 11: public static void main(String[] args) { 12: new B().go(); 13:} 14: void go() { 15: d = new A(); 16: new Thread(new B()).start(); 17: new Thread(new B()).start(); 18: } 19: public void run() { 20: d.chat(Thread.currentThread().getId()); 21: }} On the line 3, inside the synchronised chat() method, the first method call will assign the static variable flag to the same value as the current thread id. This will result in "Yo Yo " always getting printed to the print stream on the first method call to chat(). As the method is synchronised, this means that the methods variables cannot be changed by other threads calling the said method chat(). Note, the static variable flag will have changed after the first method call to chat() so therefore the second call to the method may result in "dude dude" getting appended to the print stream which could result in the following final output printed to the screen: "Yo Yo dude dude" As a consequence, D and E could never be correct with fragment I. In contrast, with fragment II, the chat() method is not synchronised. This means that variable flag can be changed by threads before the current thread completes execution on the chat() method. This could result in several sequences of strings with the first aspect of the string always being Yo For instance, the following could be a true output: "Yo dude dude Yo" As a consequence, F could be correct.
Which are true? (Choose all that apply.) A. The notifyAll() method must be called from a synchronized context B. To call wait( ), an object must own the lock on the thread C. The notify() method is defined in class java.lang.Thread D. When a thread is waiting as a result of wait(), it releases its lock E. The notify() method causes a thread to immediately release its lock F. The difference between notify( ) and notifyAll() is that notifyAll() notifies all waiting threads, regardless of the object they're waiting on
A is correct because notifyAll( ) and wait( ) and notify( ) must be called from within a synchronized context. D is a correct statement: When a thread is waiting as a result of wait(), it releases its lock Incorrect Answers B is incorrect because to call wait(), the thread must own the lock on the object that wait() is being invoked on, not the other way around. C is incorrect because notify( ) is defined in: java.lang.Object E is incorrect because notify( ) will not cause a thread to release its locks. The thread can only release its locks by exiting the synchronized code. F is incorrect because notifyAll( ) notifies all the threads waiting on a particular locked object, not all threads waiting on any object.
Given: public class A { 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
A, C, D, E and F eventually will get printed. 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 at least a one-second delay). Meanwhile, hardy tries to call laurel.wait() —but hardy has not synchronized on laurel, so calling laurel.wait() immediately causes an illegalMonitorStateException, 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. Let's step through the code: ===Code Step Through=== 1: public class A { 2: static Thread laurel, hardy; 3: public static void main(String[] args) { 4: laurel = new Thread(){ 5: public void run() { 6: System.out.println("A"); 7: try { 8: hardy.sleep(1000); 9: } 10: catch(Exception e) { 11: System.out.println("B"); 12: } 13: System.out.println("C"); 14: }}; 15: hardy = new Thread(){ 16: public void run() { 17: System.out.println("D"); 18: try { 19: laurel.wait(); 20: } catch (Exception e) { 21: System.out.println("E"); 22: } 23: System.out.println("F"); 24: }}; 25: laurel.start(); 26: hardy.start(); 27: }} On the line 4, an anonymous Thread object is created with a reference named laurel. On the line 15, another anonymous Thread object is created with a reference named hardy. Note: The new threads are created but the start() method has not been invoked on the thread. It is a live thread Thread object, but not yet a thread of execution. The thread is considered not alive. ========2======== 1: public class A { 2: static Thread laurel, hardy; 3: public static void main(String[] args) { 4: laurel = new Thread() { 5: public void run() { 6: System.out.println("A"); 7: try { 8: hardy.sleep(1000); 9: } 10: catch(Exception e) { 11: System.out.println("B"); 12: } 13: System.out.println("C"); 14: }}; 15: hardy = new Thread() { 16: public void run() { 17: System.out.println("D"); 18: try { 19: laurel.wait(); 20: } catch (Exception e) { 21: System.out.println("E"); 22: } 23: System.out.println("F"); 24: }}; 25: laurel.start(); 26: hardy.start(); 27: }} On the line 25, methods start() are called which results in the threads entering the runnable state. At a time of the JVM schedulers choosing, threads get placed in the Running state. ========3======== 1: public class A { 2: static Thread laurel, hardy; 3: public static void main(String[] args) { 4: laurel = new Thread() { 5: public void run() { 6: System.out.println("A"); 7: try { 8: hardy.sleep(1000); 9: } 10: catch(Exception e) { 11: System.out.println("B"); 12: } 13: System.out.println("C"); 14: }}; 15: hardy = new Thread() { 16: public void run() { 17: System.out.println("D"); 18: try { 19: laurel.wait(); 20: } catch (Exception e) { 21: System.out.println("E"); 22: } 23: System.out.println("F"); 24: }}; 25: laurel.start(); 26: hardy.start(); 27: }} As it is up to the JVM scheduler to decide which thread to execute first, we will choose the laurel thread to get executed first (on the line 4). On the line 5, the run() method of the laurel thread gets called (by the start() method on line 25). ========4======== 1: public class A { 2: static Thread laurel, hardy; 3: public static void main(String[] args) { 4: laurel = new Thread() { 5: public void run() { 6: System.out.println("A"); 7: try { 8: hardy.sleep(1000); 9: } 10: catch(Exception e) { 11: System.out.println("B"); 12: } 13: System.out.println("C"); 14: }}; 15: hardy = new Thread() { 16: public void run() { 17: System.out.println("D"); 18: try { 19: laurel.wait(); 20: } catch (Exception e) { 21: System.out.println("E"); 22: } 23: System.out.println("F"); 24: }}; 25: laurel.start(); 26: hardy.start(); 27: }} On the line 6, inside the run method, the letter A gets printed to the screen. ========5======== 1: public class A { 2: static Thread laurel, hardy; 3: public static void main(String[] args) { 4: laurel = new Thread() { 5: public void run() { 6: System.out.println("A"); 7: try { 8: hardy.sleep(1000); 9: } 10: catch(Exception e) { 11: System.out.println("B"); 12: } 13: System.out.println("C"); 14: }}; 15: hardy = new Thread() { 16: public void run() { 17: System.out.println("D"); 18: try { 19: laurel.wait(); 20: } catch (Exception e) { 21: System.out.println("E"); 22: } 23: System.out.println("F"); 24: }}; 25: laurel.start(); 26: hardy.start(); 27: }} On the line 7, the try block is entered and inside the try block on the line 8, the thread (referenced by hardy) is calling the method sleep(1000). 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. Program flow control then exits the try block and jumps to the line 13 which prints: C (after at least a one-second delay). At the end of line 14, the thread referenced by laurel exits the Running state and goes into the Dead state. The current output looks like: A C ========6======== 1: public class A { 2: static Thread laurel, hardy; 3: public static void main(String[] args) { 4: laurel = new Thread() { 5: public void run() { 6: System.out.println("A"); 7: try { 8: hardy.sleep(1000); 9: } 10: catch(Exception e) { 11: System.out.println("B"); 12: } 13: System.out.println("C"); 14: }}; 15: hardy = new Thread() { 16: public void run() { 17: System.out.println("D"); 18: try { 19: laurel.wait(); 20: } catch (Exception e) { 21: System.out.println("E"); 22: } 23: System.out.println("F"); 24: }}; 25: laurel.start(); 26: hardy.start(); 27: }} On the line 15, the JVM scheduler places the thread referenced by hardy into the running state. This results in the hardy method run() getting executed on the line 16. Program flow control then jumps into the run() method and prints D to the screen on the line 17. This results in the current total output looking like: A C D ========7======== 1: public class A { 2: static Thread laurel, hardy; 3: public static void main(String[] args) { 4: laurel = new Thread() { 5: public void run() { 6: System.out.println("A"); 7: try { 8: hardy.sleep(1000); 9: } 10: catch(Exception e) { 11: System.out.println("B"); 12: } 13: System.out.println("C"); 14: }}; 15: hardy = new Thread() { 16: public void run() { 17: System.out.println("D"); 18: try { 19: laurel.wait(); 20: } catch (Exception e) { 21: System.out.println("E"); 22: } 23: System.out.println("F"); 24: }}; 25: laurel.start(); 26: hardy.start(); 27: }} Program flow control jumps into the try block of the hardy referenced thread on the line 19 and tries to call laurel.wait() —but hardy has not synchronized on laurel, so calling laurel.wait() immediately causes an illegalMonitorStateException which gets caught on the line 20. Threads may be blocked because its waiting for a resource (like an I/O or object lock). This requires synchronisation of threads. Program flow control then jumps to line 21 of the catch block and prints E to the screen. Program flow control then exits the catch block and executes line 23 which prints F to the screen. This results in the final total string output: A C D E 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.
class A implements Runnable { public void run() { System.out.println("A Run"); } public static void main(String[] args) { A a = new A(); Thread t = new Thread(a); t.start(); } } The above code will give: a) compiler error b) runtime error c) compile and print "A Run" d) none of the above
C is correct. You must use the following code in order to run the thread: class A implements Runnable { public void run() { System.out.println("A Run"); } public static void main(String[] args) { A a = new A(); Thread t = new Thread(a); t.start(); } }
class B implements Runnable{ void go(){ System.out.println( Thread.currentThread().getId()); } public void run(){ go(); } public static void main(String[] args) { Thread t = new Thread(new B()); System.out.println(t.getId()); t.start(); } } The above code will output: a) 3 different id numbers b) 2 different ID numbers c) 2 ID numbers that are the same d) none of the above
C is correct. class B implements Runnable{ void go(){ System.out.println( Thread.currentThread().getId()); } public void run(){ go(); } public static void main(String[] args) { Thread t = new Thread(new B()); System.out.println( t.getId()); t.start(); } } It will print two ID numbers (t.getId()) that are the same in reference to the thread ' t '.
class A extends Thread { public static void p(String[] l){ for(int i = 0; i<l.length; i++){ System.out.print(l[i]); try { Thread.currentThread().sleep(1000); } catch(Exception e){} } } public static void main(String[] args){ p(args); } } The above code will give: a) compiler error b) runtime error c) compile and print Each string in the array l will output with a one 2nd pause between d) none of the above
C is true. class A extends Thread { public static void p(String[] l){ for(int i = 0; i<l.length; i++){ System.out.print(l[i]); try { Thread.currentThread().sleep(1000); } catch(Exception e){} } } public static void main(String[] args){ p(args); } } e.g. java A h e Will print h e with a one second pause between when h and e gets printed to screen. Note: Thread.currentThread().sleep(1000); must be placed in a try catch block.
Given: public class Logger { private StringBuilder contents = new StringBuilder(); public void log(String message) { contents.append(System.currentTimeMillis()); contents. append(": "); contents.append(Thread.currentThread().getName()); contents.append(message); contents.append("\n"); } public String getContents() { return contents.toString();} } How can we ensure that instances of this class can be safely used by multiple threads? A. This class is already thread-safe B. Replacing StringBuilder with StringBuffer will make this class thread-safe C. Synchronize the log( ) method only D. Synchronize the getContents( ) method only E. Synchronize both log( ) and getContents( ) F. This class cannot be made thread-safe
E is correct because synchronizing the public methods is sufficient to make this safe, which is why F is incorrect. This class is not thread-safe unless some sort of synchronization protects the changing data. Solution: Synchronize both log( ) and getContents( ): public class A { private StringBuilder contents = new StringBuilder(); public synchronized void log(String message) { contents.append(System.currentTimeMillis()); contents. append(": "); contents.append(Thread.currentThread().getName()); contents.append(message); contents.append("\n"); } public synchronized String getContents() { return contents.toString(); }} Incorrect Answers "B. Replacing StringBuilder with StringBuffer will make this class thread-safe" B is incorrect because although a StringBuffer is synchronized internally, we call append() multiple times, and nothing would prevent two simultaneous log() calls from mixing up their messages. ============== "C. Synchronize the log( ) method only D. Synchronize the getContents( ) method only" C and D are incorrect because if one method remains unsynchronized, it can run while the other is executing, which could result in reading the contents while one of the messages is incomplete, or worse. (You don't want to call tostring( ) on the StringBuffer as it's resizing its internal character array.) F is incorrect based on the information above.
When two threads are blocked this causes ______
DEADLOCK This occurs when two threads are blocked with each WAITING for the others LOCK. Neither can run until the other gives up its a block so they sit there forever.
class B implements Runnable{ public void run(){ System.out.print( Thread.currentThread().getId()); } public static void main(String[] args){ B b = new B(); /*Code Here*/ } } Which of the following below will print the thread ID of the B instance: a) b.run(); b) b.run().start(); c) b.start(); d) new Thread(b).start();
d is correct. class B implements Runnable{ public void run(){ System.out.print( Thread.currentThread().getId()); } public static void main(String[] args){ B b = new B(); new Thread(b).start(); } } The above code creates a new thread and starts it Incorrect Answers: a) b.run(); doesn't start a new thread therefore main thread ID thread gets printed. b) b.run().start(); gives compiler error c) b.start(); gives compiler error
import java. util.*; public class A { private List n = Collections. synchronizedList(new LinkedList()); public void mA() { n.size(); n.remove(0); } } The above code will give: a) compiler error b) runtime error c) is thread safe d) none of the above
d is correct. Even though Collections. synchronizedList(...) which enabled the collection to be thread safe a thread can be executed in BETWEEN size(); and n.remove(0); Thus corrupting the data and not making the class thread safe Solution: synchronize the method: public synchronized void mA() { n.size(); n.remove(0); } therefore threads can only access this method one at a time
What method is supposed to make the currently running thread head back to Runnable to allow other threads of the same priority to get their turn.
Thread.yield() This method is not guaranteed to work because the JVM decides overall priority. yield() will not ever cause a thread to go to the waiting/sleeping/blocking state. It is supposed to make currently running thread head back to Runnable.
class A{ static Thread a,b; public static void main(String[] args) { a = new Thread(){ public void run(){ System.out.println("A"); try { b.sleep(1000);} catch( Exception e){ System.out.println("B"); } System.out.println("C"); } }; a.start(); } } Where b is a thread that exists but is not written here. The above code will give: a) compiler error b) runtime error c) compile and print "ABC" d) none of the above
d is correct. It will print A and C. class A{ static Thread a,b; public static void main(String[] args) { a = new Thread(){ public void run(){ System.out.println("A"); try { b.sleep(1000);} catch( Exception e){ System.out.println("B"); } System.out.println("C"); } }; a.start(); } } Note: sleep() method is a static method and puts the CURRENT THREAD 'a' to sleep and not 'b'. You can call static methods with or without a reference. When 'a' eventually wakes up it will print C.
Change the code below to only synchronize the return: public Myclass { public synchronized static int m(){ return i; } }
public Myclass { public static int m(){ synchronized (MyClass.class) { return i; } } } MyClass.class is a class literal which is a special feature in the Java language to tell the compiler go and find me the instance of class that represents the class called MyClass
Change the code to synchronize the line: System.out.println("H"); in the method: public void method() { System.out.println("H"); }
public void method() { synchronized(this) { System.out.println("H"); } } 'this' refers to this instance i.e. the instance in which it is currently running
When multiple threads can access the same resource e.g. object instance variables and this may cause a ______ .
race condition. This can produce corrupted data if one thread races in too quickly BEFORE an operation from the other thread has completed.
class A { public static void main(String[] args){ B b = new B(); b.start(); synchronized(b){ try { System.out.println("waiting for b to complete"); b.wait(); } catch(Exception e) { } } } } The above code will give: a) compiler error b) runtime error c) compile and print "waiting for b to complete" d) none of the above
c is correct. class A { public static void main(String[] args){ B b = new B(); b.start(); synchronized(b){ try { System.out.println("waiting for b to complete"); b.wait(); } catch(Exception e) { } } } } Note: wait() method must be placed inside a SYNCHRONIZED BLOCK and TRY block e.g. synchronized(b){ try { System.out.println("waiting for b to complete"); b.wait(); } catch(Exception e) { } }
class A extends Thread { public void run(){ System.out.println( "A Run"); } public static void main( String[] args) { A a = new A(); a.run(); } } The above code will give: a) compiler error b) runtime error c) compile and print "A Run" d) none of the above
c is correct. class A extends Thread { public void run(){ System.out.println( "A Run"); } public static void main( String[] args) { A a = new A(); a.run(); } } It prints "A Run". Note: We HAVE NOT started the thread as we have not called the method start()
class A implements Runnable { public void run(){} public static void main(String[] args){ A a = new A(); Thread t = new Thread(a); } } The above code will give: a) compiler error b) runtime error c) compile and run fine d) none of the above
c) is correct. Runnable is an interface and the class implementing it must implement the run() method class A implements Runnable { public void run(){} public static void main(String[] args){ A a = new A(); Thread t = new Thread(a); } }
Which of the below will cause a compiler error: a ) public synchronized static void method(){ } b) public static synchronized void method(){ } c) public static void synchronized method(){ }
c) is correct. public static void synchronized method(){ } synchronised should be before void A and B will compile and run fine.
class B extends Thread { private int i; public void run(){ synchronized(this){ i++; notify(); } } } The above code will give: a) compiler error b) runtime error c) compile and run fine d) none of the above
c) is correct. class B extends Thread { private int i; public void run(){ synchronized(this){ i ++; notify(); } } } When Thread B instance is finished with variable i it notifies the other thread that is waiting for it.
Given: public class A implements Runnable { public static void main(String[] args) { Thread t = new Thread(new A()); t.start(); System.out.print("m1 "); t.join(); System.out.print("m2 "); } public void run() { System.out.print("r1 "); System.out.print("r2 "); }} Which are true? (Choose all that apply.) A. Compilation fails B. The output could be r1 r2 m1 m2 C. The output could be m1 m2 r1 r2 D. The output could be ml r1 r2 m2 E. The output could be ml r1 m2 r2 F. An exception is thrown at runtime
A is correct. Compilation fails. The join() must be placed in a try/catch block. If it were, answers B and D would be correct. Let's step through the code: ===Code Step Through=== 1: public class A implements Runnable { 2: public static void main(String[] args) { 3: Thread t = new Thread(new A()); 4: t.start(); 5: System.out.print("m1 "); 6: try { 7: t.join(); 8: } catch (InterruptedException ex) {} 9: System.out.print("m2 "); 10: } 11: public void run() { 12: System.out.print("r1 "); 13: System.out.print("r2 "); 14: }} on the line 3, a new thread instance is created and within its parameters is a class that implements the runnable interface. On the line 4, this thread is started by calling the start() method. Thread t is now in the "Runnable" state and at the time of the JVM schedulers choosing, it will be placed in the Running state. For the purposes of this example, let's assume that thread t was placed immediately into the running state at this point in time in the program execution. This results in the start() method making an implicit call to the run() method which prints the following to the screen: r1 r2 ========2======== 1: public class A implements Runnable { 2: public static void main(String[] args) { 3: Thread t = new Thread(new A()); 4: t.start(); 5: System.out.print("m1 "); 6: try { 7: t.join(); 8: } catch (InterruptedException ex) {} 9: System.out.print("m2 "); 10: } 11: public void run() { 12: System.out.print("r1 "); 13: System.out.print("r2 "); 14: }} Program flow control then jumps to line 5 which appends m1 to the output stream: r1 r2 m1 ========3======== 1: public class A implements Runnable { 2: public static void main(String[] args) { 3: Thread t = new Thread(new A()); 4: t.start(); 5: System.out.print("m1 "); 6: try { 7: t.join(); 8: } catch (InterruptedException ex) {} 9: System.out.print("m2 "); 10: } 11: public void run() { 12: System.out.print("r1 "); 13: System.out.print("r2 "); 14: }} On the line 7, the try block is entered and the thread t.join() causes the currently running thread (main() thread) to pause and joins it to the end of the thread referenced by t, meaning "m2 " must come last. In essence, t.join() means "join me (the current thread main()) to the end of t so that t is most finish before I (the current thread main()) can run again." When the t thread has completed, program flow control then resumes the main() thread and program flow control jumps onto line 9 which appends "m2" to the screen: r1 r2 m1 m2
public class A implements Runnable { public void run() { System.out.println("A Run"); } public static void main( String[] args) { A a = new A(); Thread t = new Thread(a); t.start(); t.start(); } } The above code will give: a) compiler error b) runtime error c) compile and print "A Run" twice d) none of the above
A is correct. Once a thread is started it can NEVER be started again. public class A implements Runnable { public void run() { System.out.println("A Run"); } public static void main( String[] args) { A a = new A(); Thread t = new Thread(a); t.start(); t.start(); } } If you call start() method a second time on a thread that already completed it's run() method it will give compiler error: IllegalThreadStateException Which is like RuntimeException
The following block of code creates a Thread using a Runnable target: Runnable target = new MyRunnable(); Thread myThread = new Thread(target); Which of the following classes can be used to create the target so that the preceding code compiles correctly? A. public class MyRunnable extends Runnable{public void run(){}} B. public class MyRunnable extends Object{public void run(){}} C. public class MyRunnable implements Runnable{public void run(){}} D. public class MyRunnable implements Runnable{void run(){}}
A is correct. Runnable target = new MyRunnable(); Thread myThread = new Thread(target); A: public class MyRunnable extends Runnable{ public void run(){}} Either of the two events will make the thread a candidate for running again. Incorrect Answers B is incorrect because a waiting thread will not return to runnable when the lock is released unless a notification occurs: B. public class MyRunnable extends Object { public void run(){}} C is incorrect because the thread will become a candidate immediately after notification: public class MyRunnable implements Runnable{ public void run(){}} D is also incorrect because a thread will not come out of a waiting pool just because a lock has been released: public class MyRunnable implements Runnable{ void run(){}}
Assume the following method is properly synchronized and called from a thread A on an object B: wait(2000); After calling this method, when will thread A become a candidate to get another turn at the CPU? A. After object B is notified, or after two seconds B. After the lock on B is released, or after two seconds C. Two seconds after object B is notified D. Two seconds after lock B is released
A is correct. wait(2000); After object B is notified, or after two seconds Either of the two events will make the thread a candidate for running again. Incorrect Answers B is incorrect because a waiting thread will not return to runnable when the lock is released unless a notification occurs. C is incorrect because the thread will become a candidate immediately after notification. D is also incorrect because a thread will not come out of a waiting pool just because a lock has been released.
Given: public class A { 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 A x = new A(); final A y = new A(); Runnable runnable = () -> { 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(); }} If the code compiles, 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 I. Compilation fails due to an error in declaring the Runnable
A, F, and H are correct. A. x.a() in thread1, and x.a() in thread2 A is correct because when synchronized instance methods are called on the same instance(e.g. x), they block each other: public class A { 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 A x = new A(); final A y = new A(); Runnable runnable = () -> { 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(); }} ============== F and H can't happen: F. x.b() in thread1, and x.b() in thread2 H. x.b() in thread1, and y.b() in thread2 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): public class A { 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 A x = new A(); final A y = new A(); Runnable runnable = () -> { 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(); }} Incorrect Answers C could happen: C. x.a() in thread1, and y.a() in thread2 Synchronized instance methods called on different instances (x and y) do not block each other. B, D, E, and G could all happen: B. x.a() in thread1, and x.b() in thread2 D. x.a() in thread1, and y.b() in thread2 E. x.b() in thread1, and x.a() in thread2 G. x.b() in thread1, and y.a() in thread2 This is because instance methods (e.g. a()) and static methods (e.g. b()) lock on different objects and do not block each other. Instance methods lock onto the instance object and static methods lock onto the static (singular) object I is incorrect because the code compiles.
Assume you have a class that holds two private variables: a and b. Which of the following pairs can prevent concurrent access problems in that class? (Choose all that apply.) A. public int read(){return a+b;} public void set(int a, int b){this.a=a; this.b=b;} B. public synchronized int read(){return a+b;} public synchronized void set(int a, int b){this.a=a; this.b=b;} C. public int read()(synchronized(a){return a+b;}} public void set(int a, int b){ synchronized(a){this.a=a; this.b=b;}} D. public int read()(synchronized(a){return a+b;}} public void set(int a, int b){ synchronized(b){this.a=a; this.b=b;}} E. public synchronized(this) int read(){return a+b;} public synchronized(this) void set(int a, int b){ this.a=a; this.b=b;} F. public int read()(synchronized(this){return a+b;}} public void set(int a, int b){ synchronized(this){this.a=a; this.b=b;}}
B and F are correct. B. public synchronized int read(){ return a+b; } public synchronized void set(int a, int b){ this.a=a; this.b=b; } F. public int read()( synchronized(this){ return a+b;} } public void set(int a, int b){ synchronized(this){this.a=a; this.b=b;} } By marking the methods as synchronized, the threads will get the lock of the 'this' object before proceeding. Only one thread will be setting or reading at any given moment, thereby assuring that read() always returns the addition of a valid pair. Incorrect Answers A is incorrect because it is not synchronized; therefore, there is no guarantee that the values added by the read( ) method belong to the same pair: public int read(){ return a+b; } public void set(int a, int b){ this.a=a; this.b=b; } ============== C and D are incorrect; only objects can be used to synchronize on and not anything else, including variables like 'a' or 'b': C. public int read()( synchronized(a){ return a+b;} } public void set(int a, int b){ synchronized(a){ this.a=a; this.b=b;} } D. public int read()( synchronized(a){ return a+b;} } public void set(int a, int b){ synchronized(b){ this.a=a; this.b=b;} } ============== E is incorrect because it fails to compile—it is not possible to select other objects (even this) to synchronize on when declaring a method as synchronized: public synchronized(this) int read(){ return a+b; } public synchronized(this) void set(int a, int b){ this.a=a; this.b=b; }
Given: class A extends Thread { A(){ System.out.print("MyThread "); } public void run() { System.out.print("bar "); } public void run(String s) { System.out.print("baz "); }} public class B { public static void main (String [] args){ Thread t = new A() { 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
B is correct. It prints: "MyThread foo" Let's step through the code: ===Code Step Through=== 1: class A extends Thread { 2: A(){ 3: System.out.print("MyThread "); 4: } 5: public void run() { 6: System.out.print("bar "); 7: } 8: public void run(String s) { 9: System.out.print("baz "); 10: }} 1: public class B { 2: public static void main (String [] args){ 3: Thread t = new A() { 4: public void run() { 5: System.out.print("foo "); 6: } }; 7: t.start(); 8: }} On the line 3, in the class B, we're constructing an instance of an anonymous Thread inner class extending from A. This calls the constructor A() on the line 2 of the class A. ========2======== 1: class A extends Thread { 2: A(){ 3: System.out.print("MyThread "); 4: } 5: public void run() { 6: System.out.print("bar "); 7: } 8: public void run(String s) { 9: System.out.print("baz "); 10: }} 1: public class B { 2: public static void main (String [] args){ 3: Thread t = new A() { 4: public void run() { 5: System.out.print("foo "); 6: } }; 7: t.start(); 8: }} On the line 2, the A constructor runs and prints "MyThread ". ========3======== 1: class A extends Thread { 2: A(){ 3: System.out.print("MyThread "); 4: } 5: public void run() { 6: System.out.print("bar "); 7: } 8: public void run(String s) { 9: System.out.print("baz "); 10: }} 1: public class B { 2: public static void main (String [] args){ 3: Thread t = new A() { 4: public void run() { 5: System.out.print("foo "); 6: } }; 7: t.start(); 8: }} On the line 7, the main() method invokes the start() method on the new thread instance. ========4======== 1: class A extends Thread { 2: A(){ 3: System.out.print("MyThread "); 4: } 5: public void run() { 6: System.out.print("bar "); 7: } 8: public void run(String s) { 9: System.out.print("baz "); 10: }} 1: public class B { 2: public static void main (String [] args){ 3: Thread t = new A() { 4: public void run() { 5: System.out.print("foo "); 6: } }; 7: t.start(); 8: }} On the line 4, the overridden run() method (the run() method in the anonymous inner class) is invoked. This depends the string "foo " to the screen, resulting in final output: "MyThread foo " Incorrect Answers A, C, D, E, F, G, and H are incorrect based on the logic described above.
class A { public static synchronized void main(String[] args) throws InterruptedException { Thread t= new Thread(); t.start(); System.out.println("X"); t.wait(10000); System.out.println("Y"); } } The above code will give: a) compiler error b) runtime error c) compile and print XY with a 10 second delay between X and Y d) none of the above
B is correct. The code does NOT acquire a LOCK on t before calling t.wait() method: public static synchronized void main(String[] args) throws InterruptedException { Thread t = new Thread(); t.start(); System.out.println("X"); t.wait(10000); System.out.println("Y"); } The main method is synchronized but NOT synchronized on t so the exception will be thrown: IllegalMonitorStateException Solution: If the wait() method was placed inside a: synchronized(t) block or Try/ catch block then c) would be correct i.e. The code would compile and print XY with a 10 second delay between X and Y
class A extends Thread { A(){ System.out.println("A"); } public void run(){ System.out.println("run() A"); } public void run(String s){ System.out.println("run(s)"); } public static void main(String[] args){ Thread t= new A(){ public void run(){ System.out.println("run() B"); }}; t.start(); } } The above code will give: a) compiler error b) print "A run() B" c) print "A run() A run() B" d) none of the above
B is correct. class A extends Thread { A(){ System.out.println("A"); } public void run(){ System.out.println("run() A"); } public void run(String s){ System.out.println("run(s)"); } public static void main(String[] args){ Thread t = new A(){ public void run(){ System.out.println("run() B"); } }; t.start(); } } The run(String s){} is an OVERLOADED method with parametersand this is okay. Thread t = new A(). A is a type of Thread so this is ok. Thread t = new A(){ public void run(){ System.out.println("run() B"); } }; The above is an ANONYMOUS class instantiation with run() method OVERRIDDEN. this is okay
Which of the following can be synchronized: a) instance variables b) local variables c) methods d) code blocks
C and D are correct. c) methods d) code blocks
Given: public class A implements Runnable { void go(long id) { System.out.println(id); } public static void main(String[] args) { System.out.print(Thread.currentThread().getId() + " "); //INSERT CODE HERE } public void run() { go(Thread.currentThread().getId()); } } And given the following five fragments: I. new A().run(); II. new A().start(); III. new Thread(new A()); IV. new Thread(new A()).run(); V. new Thread(new A()).start(); When the five fragments are inserted above, which are true? (Choose all that apply.) A. All five will compile B. Only one might produce the output 4 4 C. Only one might produce the output 4 2 D. Exactly two might produce the output 4 4 E. Exactly two might produce the output 4 2 F. Exactly three might produce the output 4 4 G. Exactly three might produce the output 4 2
C and D are correct. C. Only one might produce the output 4 2 D. Exactly two might produce the output 4 4 Fragment I Fragment I doesn't start a new thread. In order to start a new Thread you need to create a Thread instance containing the class that implements the Runnable interface and then call the start() method on the thread. This in turn will implicitly call the run() method. e.g. new Thread(new A()).start(); Let's step through the code: ===Code Step Through=== 1: public class A implements Runnable { 2: void go(long id) { 3: System.out.println(id); 4: } 5: public static void main(String[] args) { 6: System.out.print(Thread.currentThread().getId() + " "); 7: new A().run(); 8: } 9: public void run() { 10: go(Thread.currentThread().getId());} 11: } On the line 6, the current thread ID, which is the thread ID for the main() method gets printed to the screen. This is an arbitrary number e.g. 4 Program flow control then jumps to line 7. On the line 7, a new object instances type A is created and its method run() is called. ========2======== 1: public class A implements Runnable { 2: void go(long id) { 3: System.out.println(id); 4: } 5: public static void main(String[] args) { 6: System.out.print(Thread.currentThread().getId() + " "); 7: new A().run(); 8: } 9: public void run() { 10: go(Thread.currentThread().getId());} 11: } On the line 9, the run() method body is entered and on the line 10, a call is made to the go() method. Within the parameters of the go() method, the current thread which is the main thread ID is passed into it i.e 4 (Note: thread IDs are arbitrary numbers as they are generated randomly at runtime by the JVM) ========3======== 1: public class A implements Runnable { 2: void go(long id) { 3: System.out.println(id); 4: } 5: public static void main(String[] args) { 6: System.out.print(Thread.currentThread().getId() + " "); 7: new A().run(); 8: } 9: public void run() { 10: go(Thread.currentThread().getId());} 11: } On the line 2, the go() method is executed which prints the main thread to the screen again i.e. 4 This results in the final output of the main() thread printed twice to the screen. As the ID number of the thread is arbitrary, it could look like the following: 4 4 Fragment II Fragment II doesn't compile. The class A does not have a start() method i.e. new A().start(); Note: the start() method is located in the Thread class. This method implicitly because the run() method. Fragment III Fragment III creates a new thread but doesn't start it i.e. new Thread(new A()); Let's step through the code: ===Code Step Through=== 1: public class A implements Runnable { 2: void go(long id) { 3: System.out.println(id); 4: } 5: public static void main(String[] args) { 6: System.out.print(Thread.currentThread().getId() + " "); 7: new Thread(new A()); 8: } 9: public void run() { 10: go(Thread.currentThread().getId());} 11: } On the line 6, the current thread ID, which is the thread ID for the main() method gets printed to the screen. This is an arbitrary number e.g. 4 Program flow control then jumps to line 7. On the line 7, a new thread object instance is created and within its parameters is a new object instance of a class which implements runnable i.e. type A. Program flow control then completes leaving a possible final output: 4 Fragment IV Fragment IV creates a new thread and invokes the implemented Runnable run() method directly, but it doesn't start the new thread: new Thread(new A()).run(); Remember: The Runnable interface has one method to be implemented: run(). Let's step through the code: ===Code Step Through=== 1: public class A implements Runnable { 2: void go(long id) { 3: System.out.println(id); 4: } 5: public static void main(String[] args) { 6: System.out.print(Thread.currentThread().getId() + " "); 7: new Thread(new A()).run(); 8: } 9: public void run() { 10: go(Thread.currentThread().getId());} 11: } On the line 6, the current thread ID, which is the thread ID for the main() method gets printed to the screen. This is an arbitrary number e.g. 4 Program flow control then jumps to line 7. On the line 7, a new thread object instance is created and within its parameters is a new object instance of a class which implements runnable i.e. type A. The run() which is the implemented method of the Runnable class, is called. ========2======== 1: public class A implements Runnable { 2: void go(long id) { 3: System.out.println(id); 4: } 5: public static void main(String[] args) { 6: System.out.print(Thread.currentThread().getId() + " "); 7: new Thread(new A()).run(); 8: } 9: public void run() { 10: go(Thread.currentThread().getId());} 11: } On the line 9, the run() method body is entered and on the line 10, a method call is made to the go() method which contains the ID of the current thread i.e. the main() thread. This is the exact same ID as was retrieved on the line 6 i.e. 4 ========3======== 1: public class A implements Runnable { 2: void go(long id) { 3: System.out.println(id); 4: } 5: public static void main(String[] args) { 6: System.out.print(Thread.currentThread().getId() + " "); 7: new Thread(new A()).run(); 8: } 9: public void run() { 10: go(Thread.currentThread().getId());} 11: } On the line 2, program flow control jumps into the go() method. On the line 3, the ID of the main() method is printed to the screen i.e. 4. This results in the possible output of the thread ID of the main method getting printed twice i.e. 4 4 Fragment V Fragment V creates and starts a new thread: new Thread(new A()).start(); Let's step through the code: ===Code Step Through=== 1: public class A implements Runnable { 2: void go(long id) { 3: System.out.println(id); 4: } 5: public static void main(String[] args) { 6: System.out.print(Thread.currentThread().getId() + " "); 7: new Thread(new A()).start(); 8: } 9: public void run() { 10: go(Thread.currentThread().getId());} 11: } On the line 6, the current thread ID, which is the thread ID for the main() method gets printed to the screen. This is an arbitrary number e.g. 4 Program flow control then jumps to line 7. On the line 7, a new thread object instance is created and within its parameters is a new object instance of a class which implements runnable i.e. type A. The Thread start() method is called on the said thread. This start() then implicitly calls the run() method which is implemented on the line 9. This then creates a new thread which has its own stack and ID. ========2======== 1: public class A implements Runnable { 2: void go(long id) { 3: System.out.println(id); 4: } 5: public static void main(String[] args) { 6: System.out.print(Thread.currentThread().getId() + " "); 7: new Thread(new A()).run(); 8: } 9: public void run() { 10: go(Thread.currentThread().getId());} 11: } Program flow control then jumps into the run() method on the line 9. On the line 10, a call is made to the go() method. The method parameter of the go() contains the ID of the newly created thread on the line 7 which would have an arbitrary ID number e.g. 2 ========3======== 1: public class A implements Runnable { 2: void go(long id) { 3: System.out.println(id); 4: } 5: public static void main(String[] args) { 6: System.out.print(Thread.currentThread().getId() + " "); 7: new Thread(new A()).run(); 8: } 9: public void run() { 10: go(Thread.currentThread().getId());} 11: } On the line 2, the go() method body is entered and on the line 3 the id of the current thread is appended to the output stream i.e. 2. This results in the final total output: 4 2
Given: public class A implements Runnable { public void run() { move(Thread.currentThread().getId()); } // INSERT CODE HERE synchronized void move(long id) { System.out.print(id + " "); System.out.print(id + " "); } public static void main(String[] args) { A ch = new A(); new Thread(ch).start(); new Thread(new A()). start(); }} And given these two fragments: I. synchronized void move(long id) { II. void move(long id) { When either fragment I or fragment II is inserted above, which are true? (Choose all that apply.) A. Compilation fails B. With fragment I, an exception is thrown C. With fragment I, the output could be 4 2 4 2 D. With fragment I, the output could be 4 4 2 3 E. With fragment II, the output could be 2 4 2 4
C and E are correct. C. With fragment I, the output could be 4 2 4 2 E. With fragment II, the output could be 2 4 2 4 C is correct because, even though move() is synchronized, it's being invoked on two different objects. Let's step through the code with fragment I: ===Code Step Through=== 1: public class A implements Runnable { 2: public void run() { 3: move(Thread.currentThread().getId()); 4: } 5: synchronized void move(long id) { 6: System.out.print(id + " "); 7: System.out.print(id + " "); 8: } 9: public static void main(String[] args) { 10: A ch = new A(); 11: new Thread(ch).start(); 12: new Thread(new A()).start(); 13: }} On the line 10, a new object instance of A is created. ========2======== 1: public class A implements Runnable { 2: public void run() { 3: move(Thread.currentThread().getId()); 4: } 5: synchronized void move(long id) { 6: System.out.print(id + " "); 7: System.out.print(id + " "); 8: } 9: public static void main(String[] args) { 10: A ch = new A(); 11: new Thread(ch).start(); 12: new Thread(new A()).start(); 13: }} On the line 11, a new new Thread() object is created with the instance of the class A (with reference ch) passed in as a parameter. The thread start() method is called which implicitly calls the run() method when the JVM scheduler decides to place the thread in the running state. It is now currently in the runnable state. On the line 12 it is the same process except a new object instance new A() is created and passed into the thread. The thread start() method is called which implicitly calls the run() method when the JVM scheduler decides to place the thread in the running state. It is now currently in the runnable state. ========3======== 1: public class A implements Runnable { 2: public void run() { 3: move(Thread.currentThread().getId()); 4: } 5: synchronized void move(long id) { 6: System.out.print(id + " "); 7: System.out.print(id + " "); 8: } 9: public static void main(String[] args) { 10: A ch = new A(); 11: new Thread(ch).start(); 12: new Thread(new A()).start(); 13: }} For the purposes of this example, the new thread (created on the line 11) will be placed in the running state first (executed first). When the thread is placed in the running state, an implicit call is made to its run() method by its start() method declared on the line 11. On the line 3, inside the run() method, a method call is made to the move() method whose parameter contains thread ID of the current thread. This thread ID can be an arbitrary number e.g. 4 ========4======== 1: public class A implements Runnable { 2: public void run() { 3: move(Thread.currentThread().getId()); 4: } 5: synchronized void move(long id) { 6: System.out.print(id + " "); 7: System.out.print(id + " "); 8: } 9: public static void main(String[] args) { 10: A ch = new A(); 11: new Thread(ch).start(); 12: new Thread(new A()).start(); 13: }} On the line 5, the move method is entered and the id of the current thread could be printed twice: 4 4 It is important to note, even though move() is synchronized, it's being invoked on two different objects (ch and new A()). As these objects have two distinct thread IDs, the method call to each of the objects move() method maybe done concurrently. This means that the IDs may be printed to the print stream in sequence or non-sequence. Therefore, the C is correct: With fragment I, the output could be: 4 2 4 2 or 4 4 2 2 With reference to fragment II, D could be correct: 2 4 2 4 or 4 2 4 2
class A implements Runnable { public void run(){ for(int i = 0; i<3; i++) { System.out.print( i+".."); } } public static void main(String[] args) { A a = new A(); Thread t = new Thread(a); t.start(); } } The above code will give: a) compiler error b) runtime error c) print "0..1..2.." d) none of the above
C is correct. class A implements Runnable { public void run(){ for(int i = 0; i<3; i++) { System.out.print( i+".."); }} public static void main(String[] args) { A a = new A(); Thread t = new Thread(a); t.start(); } } Print: "0..1..2.."
class A implements Runnable{ public void run(){ System. out. println("r"); } public static void main(String[] args){ Thread t = new Thread(new A()); t.start(); System.out.println("m1"); try { t.join(); }catch(Exception e){} System.out.println("m2"); } } The above code will give: a) compiler error b) runtime error c) compile and print 'm1rm2' d) none of the above
C is correct. The code will compile and print: m1 r m2 class A implements Runnable{ public void run(){ System. out. println("r"); } public static void main(String[] args){ Thread t = new Thread(new A()); t.start(); System.out.println("m1"); try { t.join(); }catch(Exception e){} System.out.println("m2"); } } In the above code, the thread with reference t gets instantiated. This thread is started with the method start(). This thread is then placed in the queue for execution. Program flow control then jumps to the which prints "m1". The method t.join() waits for thread t to die. Join method in Java allows one thread to wait until another thread completes its execution. In simpler words, it means it waits for the other thread to die. When the thread is available for execution, it's run() (which was implicitly called by the join()method) is called which prints "r" before the thread dies. Join method throws an InterruptedException. This is caught which results in "m2" to the output stream. Note: An InterruptedException is thrown when a thread is waiting, sleeping, or otherwise occupied, and the thread is interrupted, either before or during the activity. Solution Amend the code of the run method to incorporate it to sleep: class A implements Runnable{ public void run(){ System. out. println("r"); for(int i=1;i<=4;i++){ try{ Thread.sleep(200); }catch(Exception e){System.out.println(e);} } public static void main(String[] args){ Thread t = new Thread(new A()); t.start(); System.out.println("m1"); try { t.join(); }catch(Exception e){} System.out.println("m2"); } }
class A { public static void main(String[] args) { Thread t= new Thread(); t.start(); System.out.println("X"); try { t.wait(10000); } catch(Exception e) { } System.out.println("Y"); } } The above code will give: a) compiler error b) runtime error c) compiles and print XY with a 10 second delay between X and Y d) none of the above
C is correct. Compiles and print XY with a 10 second delay between X and Y. class A { public static void main(String[] args) { Thread t = new Thread(); t.start(); System.out.println("X"); try { t.wait(10000); } catch(Exception e) { } System.out.println("Y"); } } The wait() method needs to be placed in a try/catch block or within a synchronized block.
Given: 1: public class A { 2: public static void main(String[] args){ 3: System.out.print("1 "); 4: synchronized(args){ 5: System.out.print("2 "); 6: try { 7: args.wait(); 8: } 9: catch(InterruptedException e ){} 10: } 11: System.out.print("3 "); 12: }} What is the result of trying to compile and run this program? A. It fails to compile because the IllegalMonitorStateException of wait() is not dealt with in line 7 B. 1 2 3 C. 1 3 D. 1 2 E. At runtime, it throws an IllegalMonitorStateException when trying to wait F. It will fail to compile because it has to be synchronized on the "this" object
D is correct. 1 and 2 will be printed, but there will be no return from the wait call because no other thread will notify the main thread, so 3 will never be printed. It's frozen at line 7. Let's step through the code: ===Code Step Through=== 1: public class A { 2: public static void main(String[] args){ 3: System.out.print("1 "); 4: synchronized(args){ 5: System.out.print("2 "); 6: try { 7: args.wait(); 8: } 9: catch(InterruptedException e ){} 10: } 11: System.out.print("3 "); 12: }} On the line 3, the digit 1 gets printed to the screen. ========2======== 1: public class A { 2: public static void main(String[] args){ 3: System.out.print("1 "); 4: synchronized(args){ 5: System.out.print("2 "); 6: try { 7: args.wait(); 8: } 9: catch(InterruptedException e ){} 10: } 11: System.out.print("3 "); 12: }} On the line 4, the synchronised block is entered with the object reference args passed into it. ========3======== 1: public class A { 2: public static void main(String[] args){ 3: System.out.print("1 "); 4: synchronized(args){ 5: System.out.print("2 "); 6: try { 7: args.wait(); 8: } 9: catch(InterruptedException e ){} 10: } 11: System.out.print("3 "); 12: }} On the line 5, within the synchronised block, the digit 2 gets printed to the screen. ========4======== 1: public class A { 2: public static void main(String[] args){ 3: System.out.print("1 "); 4: synchronized(args){ 5: System.out.print("2 "); 6: try { 7: args.wait(); 8: } 9: catch(InterruptedException e ){} 10: } 11: System.out.print("3 "); 12: }} On the line 7, the wait() method gets executed on the args object reference. When you want to wait for something, you also need to be able to check if it is already happening. Generally, the best way to solve this is to put in some sort of loop around the wait() method. Otherwise, it will cause an infinite loop as in this case. there will be no return from the wait() call because no other thread will notify the main thread, so 3 will never be printed. This results in the final output: 1 2 Incorrect Answers A is incorrect; IllegalMonitorStateException is an unchecked exception. An unchecked exception does not need to be declared in a try catch block. B and C are incorrect; 3 will never be printed, since this program will wait forever. java.lang.Object.wait() causes current thread to wait until another thread invokes the notify() method or the notifyAll() method for this object. ============== E is incorrect because IllegalMonitorStateException will never be thrown because the wait( ) is completed on args within a block of code synchronized on args. F is incorrect because any object can be used to synchronize on, and this and static don't mix.
You have two threads, t1 and t2, attemping to access a shared resource, and t2 is always descheduled when it tries to access that resource. What is this kind of problem called? A. A race condition B. Deadlock C. Livelock D. Starvation E. Synchronization F. Multitasking
D is correct. Starvation occurs when one or more threads cannot get access to a resource.
class A { private StringBuilder c = new StringBuilder(); public void log(){ Thread.currentThread().getName(); } public String getlog(){ return c.toString(); } } How can we make the above class thread safe? a) this class is already thread safe b) Replacing StringBuilder with StringBuffer c) synchronize the log() method only d) none of the above
D is correct. Synchronizing the public methods is sufficient to make this class thread safe i.e. class A { private StringBuilder c = new StringBuilder(); public synchronized void log(){ Thread.currentThread().getName(); } public synchronized String getlog(){ return c.toString(); } }
Given: class A extends Thread { public static void main(String[]args) { A t = new A(); Thread x = new Thread(t); x.start(); } public void run() { for(int i=0;i<3;++i) { System.out.print(i +".."); } }} What is the result of this code? A. Compilation fails B. 1..2..3.. C. 0..2..3.. D. 0..1..2.. E. An exception occurs at runtime
D is correct. The thread MyThread will start and loop three times (from 0 to 2). Let's step through the code: ===Code Step Through=== 1: class A extends Thread { 2: public static void main(String[]args) { 3: A t = new A(); 4: Thread x = new Thread(t); 5: x.start(); 6: } 7: public void run() { 8: for(int i=0;i<3;++i) { 9: System.out.print(i +".."); 10: } 11: }} On the line 1, the class A extends the class Thread. The class Thread is located in the java.lang.Thread and does not need to be implicitly stated in the code. An instance of Thread is just an object which has variables and methods, and it lives and dies on the heap. The main method, which starts the whole ball rolling, runs in one thread, called surprisingly, the main() Thread. The limitation with this approach is that if you extend Thread , you can't extend anything else. As an alternative, you could implement Runnable interface. The Thread class implements the Runnable interface. ========2======== 1: class A extends Thread { 2: public static void main(String[]args) { 3: A t = new A(); 4: Thread x = new Thread(t); 5: x.start(); 6: } 7: public void run() { 8: for(int i=0;i<3;++i) { 9: System.out.print(i +".."); 10: } 11: }} On the line 3, an instance of the class A is created. On the line 4, an instance of Thread is created and the reference to an A object is passed into its constructor. You can only pass objects that implement Runnable into the Thread class constructor. The Thread class implements the Runnable interface. As class A extends Thread, class A is also thread which implements the Runnable interface. Therefore, in line 4, Thread can take an object of type A as an argument in the constructor (this is NOT recommended). ========3======== 1: class A extends Thread { 2: public static void main(String[]args) { 3: A t = new A(); 4: Thread x = new Thread(t); 5: x.start(); 6: } 7: public void run() { 8: for(int i=0;i<3;++i) { 9: System.out.print(i +".."); 10: } 11: }} On the line 5, the Thread method start() gets executed. This method starts the thread. This method implicitly calls the run() method. When the start method is called the following occurs: ➤ A new thread of execution starts (with a new call stack). ➤ The thread moves from the new state to the runnable state. ➤ When the thread gets a chance to execute, its target run() method will run. You start a Thread instance, not a Runnable interface. ========4======== 1: class A extends Thread { 2: public static void main(String[]args) { 3: A t = new A(); 4: Thread x = new Thread(t); 5: x.start(); 6: } 7: public void run() { 8: for(int i=0;i<3;++i) { 9: System.out.print(i +".."); 10: } 11: }} On the line 7, the run() method gets entered. On the line 8, the for loop gets executed which prints the following to the screen: 0..1..2.. Note: The run() method is the place where the separate job (or thing to do) is run in its own thread. You always write the code that needs to be run in a separate thread in a run() method. This creates a new call stack. Incorrect Answers B and C are incorrect because the variable i in the for loop starts with a value of 0 and ends with a value of 2. E is incorrect based on the above.
Given: class A { public static void main(String [] args) { printAll(args); } public static void printAll(String[] lines){ for(int i=0;i<lines.length;i++){ System.out.println(lines[i]); Thread.currentThread().sleep(1000); } }} The static method Thread. currentThread() returns a reference to the currently executing Thread object. What is the result of this code? A. Each String in the array lines will output, with a one-second pause between lines B. Each String in the array lines will output, with no pause in between because this method is not executed in a Thread C. Each String in the array lines will output, and there is no guarantee that there will be a pause because currentThread ( ) may not retrieve this thread D. This code will not compile E. Each String in the lines array will print, with at least a one-second pause between lines
D is correct. This code will not compile. The sleep() method must be enclosed in a try/catch block, or the method printAll( ) must declare it throws the InterruptedException. class A { public static void main(String [] args) { printAll(args); } public static void printAll(String[] lines){ for(int i=0;i<lines.length;i++){ System.out.println(lines[i]); Thread.currentThread().sleep(1000); } }} Incorrect Answers E is incorrect, but it would be correct if the InterruptedException was dealt with (answer A is too precise). B is incorrect (even if the InterruptedException was dealt with) because all Java code, including the main( ) method, runs in threads. C is incorrect. The sleep() method is static; it always affects the currently executing thread.
class A extends Thread { public void run(){ for(int i = 0; i<3; i++){ System.out.print( i+".."); } } public static void main(String[] args){ A a = new A(); Thread t = new Thread(a); t.start(); } } The above code will give: a) compiler error b) runtime error c) print "0..1.." d) none of the above
D is correct. class A extends Thread { public void run(){ for(int i = 0; i<3; i++){ System.out.print( i+".."); } } public static void main(String[] args){ A a = new A(); Thread t = new Thread(a); t.start(); } } Prints "0..1..2.."
class A { public static void main (String[] args){ System.out.print("1"); synchronized(args){ System.out.print("2"); try{ args.wait(); } catch(InterruptedException e) { } } System.out.print("3"); } } The above code will give: a) compiler error b) runtime error c) compile and print 123 d) none of the above
D is correct. class A { public static void main(String[] args){ System.out.print("1"); synchronized(args){ System.out.print("2"); try{ args.wait(); } catch(InterruptedException e) { } } System.out.print("3"); } } It prints 1 then goes into the synchronized block and prints 2 and then WAITS INFINITELY because no other thread will notify the main thread. Note: args is an object reference to the print stream so you pass this to synchronized(args) {}
Given: class A { synchronized void yack(long id) { for(int x = 1; x < 3; x++) { System.out.print(id + " "); Thread.yield(); }}} public class B implements Runnable { A c; public static void main(String [] args) { new B().go(); } void go() { c = new A(); new Thread(new B()).start(); new Thread(new B()).start(); } public void run(){ c.yack(Thread.currentThread().getId()); }} Which are true? (Choose all that apply.) A. Compilation fails B. The output could be 4 C. The output could be 4 D. The output could be 4 E. The output could be 2 F. An exception is thrown at runtime
F is correct. An exception is thrown at runtime Let's step through the code: ===Code Step Through=== 1: class A { 2: synchronized void yack(long id) { 3: for(int x = 1; x < 3; x++) { 4: System.out.print(id + " "); 5: Thread.yield(); 6: }}} 7: public class B implements Runnable { 8: A c; 9: public static void main(String [] args) { 10: new B().go(); 11: } 12: void go() { 13: c = new A(); 14: new Thread(new B()).start(); 15: new Thread(new B()).start(); 16: } 17: public void run(){ 18: c.yack(Thread.currentThread().getId()); 19: }} On the line 10, new instance of class B is created and a call is made to its method go(). ========2======== 1: class A { 2: synchronized void yack(long id) { 3: for(int x = 1; x < 3; x++) { 4: System.out.print(id + " "); 5: Thread.yield(); 6: }}} 7: public class B implements Runnable { 8: A c; 9: public static void main(String [] args) { 10: new B().go(); 11: } 12: void go() { 13: c = new A(); 14: new Thread(new B()).start(); 15: new Thread(new B()).start(); 16: } 17: public void run(){ 18: c.yack(Thread.currentThread().getId()); 19: }} On the line 13, a new object instance of type A is created and referenced by 'c' which is nonstatic. On the line 14 and 15, within the go() method block, two new threads are created (in sequence) containing the class B which implements runnable. These threads are started using the start() method, which implicitly call the run() method on the line 17. The threads are placed in the "Runnable" state by the JVM scheduler and at the time of JVMs choosing, it will place the thread in the running state. ========3======== 1: class A { 2: synchronized void yack(long id) { 3: for(int x = 1; x < 3; x++) { 4: System.out.print(id + " "); 5: Thread.yield(); 6: }}} 7: public class B implements Runnable { 8: A c; 9: public static void main(String [] args) { 10: new B().go(); 11: } 12: void go() { 13: c = new A(); 14: new Thread(new B()).start(); 15: new Thread(new B()).start(); 16: } 17: public void run(){ 18: c.yack(Thread.currentThread().getId()); 19: }} For the purposes of this example, let's assume that the first thread entering the running state is online 14. On the line 18, the run() method is implicitly called by the start() method on the line 14. This particular object instance B (created on the line 14) has not made an explicit call to its go() method. It is within this go() method that the reference 'c' is assigned to an object instance of class A. However, as there has been no call made by this particular object instance (on the line 14) to its go() method, this throws a java.lang.NullPointerException Solution: If 'c' were static, then because yack() is synchronized, answers C and E would have been correct.
Given: public class A { public static synchronized void main(String[] args) throws InterruptedException { Thread t = new Thread(); t.start(); System.out.print("X"); t.wait(10000); System.out.print("Y"); }} What is the result of this code? A. It prints x and exits B. It prints x and never exits C. It prints xY and exits almost immediately D. It prints XY with a 10-second delay between x and Y E. It prints XY with a 10,000-second delay between x and Y F. The code does not compile G. An exception is thrown at runtime.
G is correct. The code does not acquire a lock on "t" before calling t.wait( ), so it throws an IllegalMonitorStateException. The method is synchronized, but it's not synchronized on "t" so the exception will be thrown. If the wait() were placed inside a synchronized(t) block, then D would be correct. Solution 1 public class A { public static synchronized void main(String[] args) throws InterruptedException { Thread t = new Thread(); synchronized( t ){ t.start(); System.out.print("X"); t.wait(10000); System.out.print("Y"); }}} Solution 1 will print: XY Solution 2 public class A { public static synchronized void main(String[] args) throws InterruptedException { Thread t = new Thread(); try { t.start(); System.out.print("X"); t.wait(10000); System.out.print("Y"); } catch (Exception e) {} }} Solution 2 will output: X
Which are true? Choose all that apply: a) The notifyAll() method must be called from a synchronized context b) to call the wait() method an object must own the lock on the thread c) the notify() method is defined in the class java.lang.Thread d) When a thread is waiting as a result of a wait() method call it releases its lock
a) and d) are correct. A is correct because notifyAll() wait() and notify() method must be called from within a SYNCHRONIZED block or method. B is incorrect because to call the wait() method the thread must OWN the lock on the OBJECT that the wait() method is being INVOKED ON NOT the other way around. C is incorrect because the notify() method is defined in java.lang.Object D is incorrect because the notify() method will NOT cause a thread to release its locks.
class A implements Runnable { void run(){} public static void main(String[] args) { A a = new A(); Thread t = new Thread(a); } } The above code will give: a) compiler error b) runtime error c) compile and run fine d) none of the above
a) is correct. class A implements Runnable { void run(){} public static void main(String[] args) { A a = new A(); Thread t = new Thread(a); } } The run() method should be EXPLICITLY PUBLIC as it is implicitly in the interface Runnable i.e. public void run(){}
Which of the following are true: a) each object has just one lock b) each object can have more than one lock
a) is correct. each object has just ONE lock
class A implements Runnable { public void start(){} public static void main(String[] args) { A a = new A(); Thread t = new Thread(a); } } The above code will give: a) compiler error b) runtime error c) compile and run fine d) none of the above
a) is correct. A should implement the sole method within Runnable which is run() and not start() which is located in java.lang.Thread class A implements Runnable { public void start(){} public static void main(String[] args) { A a = new A(); Thread t = new Thread(a); } }
class A implements Runnable{ public void run(){ System. out. println( "r"); } public static void main(String[] args) { Thread t = new Thread(new A()); t.start(); t.join(); System.out.println("m1"); } } The above code will give: a) compiler error b) runtime error c) compile and print 'rm1' d) none of the above
a) is correct. The code will give a compiler error. class A implements Runnable{ public void run(){ System. out. println( "r"); } public static void main(String[] args) { Thread t = new Thread(new A()); t.start(); t.join(); System.out.println("m1"); } } The method t.join() must be placed in the try catch block. If this was the case then c) would be correct i.e. compile and print rm1
class B implements Runnable{ private String n; B(String s){n = s;} public void run(){ for(int i = 0; i<3000; i++){ System.out.println(n); } } public static void main(String[] args) { new Thread(new B("hi")).start(); new Thread(new B("lo")).start(); }} The above code will give: a) compiler error b) runtime error c) prints "hi" 3000 times then "lo" 3000 times d) none of the above
d is correct. The run() method is not SYNCHRONIZED therefore the run() method doesn't have a lock on printing to screen therefore "hi" and "lo" get printed 3000 times each but in MIXED ORDER. Solution: Encapsulate the body of the run() method in a synchronised block then the JVM will print a certain amount of hi's followed by a certain amount of lo's followed by a certain amount of hi's ........ until all have been printed. class B implements Runnable{ private String n; B(String s){n = s;} public void run(){ synchronised(this){ for(int i = 0; i<3000; i++){ System.out.println(n); } } } public static void main(String[] args) { new Thread(new B("hi")).start(); new Thread(new B("lo")).start(); }} Note: JVM will use the Operating system threading model to control thread state
class B implements Runnable { void go(){ System.out.println( Thread.currentThread().getId()); } public void run(){ go(); } public static void main(String[] args){ System.out.println(Thread.currentThread().getId()); Thread t = new Thread(new B()); System.out.println(t.getId()); t.start(); } } The above code will output: a) 3 different id numbers b) 2 different ID numbers c) 3 ID numbers that are the same d) none of the above
d) is correct. It will print two ID numbers that are the same in reference to the thread 't' (t.getId()) and one different ID number in reference to the MAIN thread ID (Thread.currentThread().getId()) e.g. 1 8 8 class B implements Runnable { void go(){ System.out.println(Thread.currentThread().getId()); } public void run(){ go(); } public static void main(String[] args){ System.out.println(Thread.currentThread().getId()); Thread t = new Thread(new B()); System.out.println(t.getId()); t.start(); } }
A thread in Java begins as an instance of which class?
java.lang.Thread
How can we solve the race condition on a method
make the method synchronized e.g. public synchronized void m() { .... } only one thread can access this method at a time
List the thread states and transitions
➤ 1 New State This is the state the thread in after the thread instance has been created but the start() method has not been invoked on the trade e.g. Thread t = new Thread() ➤ 2 Runnable State This is the state the thread is in when it's eligible to run but the scheduler has not selected it to be the running thread. A thread first enters the runnable state when the t.start() method is invoked. ➤ 3 Running State This is the state a thread is in when the thread scheduler selects it from the runnable pool to be executed. ➤ 4 Waiting State/ blocked/ sleeping This is the state a thread is in when it's not eligible to run. In essence, it is not runnable but it might return to a runnable state later if a particular event occurs e.g. sleep() or yield() ➤ 5 Dead State A thread is considered dead when it's run() method completes. If you invoke start() method on a dead thread instance, you'll get an exception at one time.
List 2 ways to define and instantiate a thread
➤Extend the java.lang.Thread class i.e. class A extends Thread {...} ➤Implement the Runnable interface i.e. class A implement Runnable {...}
