0% found this document useful (0 votes)
3 views8 pages

Java Threads Practice MCQs

Uploaded by

Mariam Khalifa
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views8 pages

Java Threads Practice MCQs

Uploaded by

Mariam Khalifa
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd

Concurrent Execution with Java Threads

Practice Exam — Multiple Choice Questions

Instructions: Choose the single best answer (A–D) for each question. There are 29 questions
covering thread basics, thread creation, the thread lifecycle, race conditions, synchronization rules,
interrupts, interthread communication, and deadlocks. The answer key with explanations begins on
a new page after the questions.
Name: ____________________________ Date: ______________

1. What is a thread in Java, as defined in the lecture?


A. A separate process with its own independent memory space
B. A lightweight, independent unit of execution inside a program (process)
C. A class that can only be created by extending the Thread class
D. A method that runs only when the JVM starts

2. Which of the following is NOT listed as a reason to implement multithreading?


A. Improved performance through concurrent task execution
B. Better resource utilization due to shared memory space
C. Responsive applications while heavy computing runs in the background
D. Guaranteed elimination of all race conditions

3. In the JVM process diagram, what do the main thread and the spawned Java
threads share?
A. Nothing — each thread has a completely isolated memory space
B. Only the CPU registers
C. The exact same shared memory space and resources as the parent process
D. A separate JVM instance for each thread

4. What is the main limitation of creating a thread by extending the Thread class?
A. You cannot override the run() method
B. You cannot extend any other class, due to Java's single inheritance rule
C. It requires implementing the Runnable interface anyway
D. It cannot be started using start()

5. Why is implementing the Runnable interface generally preferred over extending


Thread?
A. It runs faster than extending Thread
B. It is the only way to override run()
C. It is more flexible, allowing the class to extend another class simultaneously
D. Runnable objects do not need a start() call
6. Which method must be overridden in both the 'extends Thread' and 'implements
Runnable' approaches to define the task a thread performs?
A. main()
B. start()
C. run()
D. execute()

7. When using the Runnable approach, how is the thread actually launched?
A. By calling run() directly on the Runnable object
B. By passing the Runnable object to a Thread constructor and calling that Thread's start()
method
C. By calling the Runnable's execute() method
D. Runnable objects launch automatically when instantiated

8. In the CookingTask example, what happens when [Link](), [Link](), [Link](), and
[Link]() are all called in sequence?
A. They run strictly one after another in the order called, guaranteed
B. Only the last started thread actually executes
C. Each thread gets its own call stack and can run concurrently, so the output order may vary
D. The program throws a compilation error because multiple threads cannot share a class

9. A student calls run() directly on a Thread object instead of calling start(). What is
the key consequence?
A. It throws an InterruptedException
B. It behaves identically to start() in every way
C. The code executes sequentially in the calling thread rather than launching a new concurrent
thread
D. The JVM automatically converts the call into start()

10. According to the Thread Lifecycle diagram, in which state does a thread actually
execute its instructions?
A. New
B. Runnable
C. Blocked
D. Terminated

11. Which of these is grouped under the 'Pause States' in the thread lifecycle
diagram?
A. New, Runnable, Terminated
B. Blocked, Waiting, Timed Waiting
C. Runnable, Terminated, New
D. Started, Stopped, Resumed
12. Why does the bank account 'bad example' produce an incorrect or unpredictable
final balance when two threads call withdraw() concurrently?
A. Because withdraw() is a static method
B. Because both threads read and write the same shared 'balance' variable without
coordination, causing a race condition
C. Because Java does not allow two threads to call the same method
D. Because the Thread constructor was called incorrectly

13. What is Rule 1 for preventing concurrency glitches, as stated in the lecture?
A. Always use the Runnable interface instead of extends Thread
B. Minimize sharing — share as few attributes between threads as possible
C. Always call run() instead of start()
D. Never use more than two threads in a program

14. In the corrected WithdrawalTask example (Rule 1), how is the race condition
avoided?
A. By making the balance variable static
B. By having each thread only store its own withdrawal request locally, then letting the main
thread safely combine results after both threads finish via join()
C. By starting both threads but never actually calling start()
D. By using the deprecated stop() method

15. What is the purpose of [Link]() in the corrected bank example?


A. It merges two threads into a single thread object
B. It makes the calling (main) thread wait until t1 has finished executing before proceeding
C. It immediately terminates thread t1
D. It restarts thread t1 from the beginning

16. According to Rule 2 in the lecture, what is isAlive() used for?


A. To restart a terminated thread
B. To check whether a thread has fully finished running, acting as a check-valve before the
main program touches shared attributes
C. To pause a thread indefinitely
D. To check if a thread has thrown an exception

17. In the IsAliveWithdrawThreadBankExample, why does t2 only attempt its


withdrawal after the while([Link]()) loop finishes?
A. Because [Link]() is called inside the loop body
B. Because the loop deliberately busy-waits, blocking the main thread from calling [Link]()
until t1 has terminated
C. Because Java automatically queues thread start calls
D. Because t1 and t2 share no resources
18. In the Flashing Text example, what is the purpose of [Link](500) inside the
for loop?
A. To permanently pause the thread until interrupted
B. To pause execution for 500 milliseconds between each text toggle, creating the flashing
effect
C. To kill the thread after 500 iterations
D. To synchronize access to the JLabel

19. Why must [Link]() calls typically be wrapped in a try/catch for


InterruptedException?
A. Because sleep() always throws an exception
B. Because sleep() is designed to cancel its current operation and return immediately (via the
exception) if the thread is interrupted while sleeping
C. Because Java requires all methods to have try/catch blocks
D. Because InterruptedException is a compile-time syntax requirement only, with no real effect

20. In the InterruptExample program, what is the most likely cause of the worker
thread printing 'Thread was interrupted!' and then terminating?
A. The worker thread finished its while(true) loop naturally
B. The main thread called [Link](), which threw an InterruptedException inside the
worker's [Link](2000) call
C. The JVM ran out of memory
D. The worker thread called [Link]()

21. Which pair of Object class methods allows a thread to give up the monitor and
sleep until another thread wakes it?
A. start() and stop()
B. wait() and notify()/notifyAll()
C. sleep() and resume()
D. join() and interrupt()

22. Why must wait(), notify(), and notifyAll() be called only inside synchronized
blocks or methods?
A. Because they belong to the Thread class and require synchronization by definition
B. Because they operate on an object's monitor/lock, which a thread must hold in order to
safely call them
C. Because Java forbids calling them anywhere else for syntactic reasons unrelated to locking
D. They don't actually require synchronization — that is a common myth

23. In the flawed (first) Producer-Consumer example without wait/notify, what


problem can occur, as suggested by the sample output showing repeated 'Got: 1'
lines?
A. The consumer can read the same value multiple times before the producer produces a new
one, or values can be skipped entirely
B. The producer and consumer cannot run at the same time at all
C. The program throws a compilation error
D. The queue automatically blocks duplicate reads
24. In the corrected Producer-Consumer example, what does the boolean 'valueSet'
flag combined with wait()/notify() achieve?
A. It makes put() and get() run on separate threads without any locking
B. It ensures the producer waits if a value hasn't been consumed yet, and the consumer waits if
no new value has been produced yet, alternating Put/Got pairs correctly
C. It prevents the producer from ever calling notify()
D. It removes the need for the synchronized keyword

25. How is deadlock defined in the lecture?


A. A situation where a thread runs out of CPU time and is terminated
B. A situation where two or more threads are permanently blocked because each is waiting for
the other to release a required lock
C. A situation where a single thread enters an infinite loop without using any locks
D. A situation where a thread throws an uncaught exception

26. In the A/B deadlock example (class A and class B with synchronized foo(), bar(),
and last() methods), what causes the deadlock?
A. The main thread holds the lock on object 'a' and tries to call [Link](), while the racing thread
holds the lock on object 'b' and tries to call [Link]() — each waits on a lock the other holds
B. Both threads try to access the same exact method at the same exact time
C. The [Link](1000) call inside foo() throws an exception
D. Class A and class B are not allowed to reference each other in Java

27. Which four conditions must all be present simultaneously for a deadlock to
occur, according to the lecture?
A. Mutual Exclusion, Hold and Wait, No Preemption, Circular Wait
B. Race Condition, Starvation, Livelock, Thread Priority Inversion
C. New, Runnable, Blocked, Terminated
D. Improved Performance, Resource Utilization, Responsiveness, Scalability

28. How do locks, as illustrated in Figure 2 of the Deadlock Prevention slide, help
prevent the deadlock shown in Figure 1?
A. By removing the need for any resource access entirely
B. By controlling which thread holds a resource versus which thread must wait, making the
lock/wait relationship explicit and manageable rather than an uncontrolled circular dependency
C. By forcing all threads to run on the same single core
D. By deleting one of the two competing threads automatically

29. Which of the following best distinguishes start() from run()?


A. start() and run() are interchangeable in every situation
B. start() launches a brand-new thread and invokes run() concurrently, while calling run()
directly executes sequentially with no new thread
C. run() can only be called once, while start() can be called many times on the same thread
D. start() is part of Runnable but not Thread
Answer Key & Explanations
1. Answer: B — A lightweight, independent unit of execution inside a program (process)
A thread is described as a lightweight, independent unit of execution inside a program (process), not
a separate process.
2. Answer: D — Guaranteed elimination of all race conditions
Multithreading does not eliminate race conditions — in fact shared memory introduces the risk of
race conditions, which is why synchronization rules are needed.
3. Answer: C — The exact same shared memory space and resources as the parent process
Threads operate concurrently while sharing the exact same memory and resources as the parent
process.
4. Answer: B — You cannot extend any other class, due to Java's single inheritance rule
Because Java only allows single inheritance, a class that extends Thread cannot also extend any
other class.
5. Answer: C — It is more flexible, allowing the class to extend another class simultaneously
Implementing Runnable is described as extremely flexible since it allows extending another class at
the same time, and is preferred in most cases.
6. Answer: C — run()
Both paths require overriding run() to define the code that will execute inside the thread.
7. Answer: B — By passing the Runnable object to a Thread constructor and calling that
Thread's start() method
An instance implementing Runnable is passed to a Thread object's constructor, and then
[Link]() is called.
8. Answer: C — Each thread gets its own call stack and can run concurrently, so the output
order may vary
Calling start() creates a new thread with its own call stack; because thread scheduling is non-
deterministic, the order of output can vary on each run.
9. Answer: C — The code executes sequentially in the calling thread rather than launching a
new concurrent thread
start() launches a brand-new thread and calls run() concurrently; calling run() directly just executes
that method sequentially in the current thread, with no new thread created.
10. Answer: B — Runnable
Execution happens in the Runnable state; Blocked, Waiting, and Timed Waiting are pause states a
thread can transition into and out of before reaching Terminated.
11. Answer: B — Blocked, Waiting, Timed Waiting
The pause states shown are Blocked, Waiting, and Timed Waiting — a thread enters these due to
memory locks or deliberate pauses before returning to Runnable.
12. Answer: B — Because both threads read and write the same shared 'balance' variable
without coordination, causing a race condition
Both threads check and modify the same shared balance variable concurrently; without
synchronization, both can pass the if-check before either updates balance, leading to an incorrect
(even negative) result.
13. Answer: B — Minimize sharing — share as few attributes between threads as possible
Rule 1 states the best defense against concurrency problems is to share as few attributes between
threads as possible.
14. Answer: B — By having each thread only store its own withdrawal request locally, then
letting the main thread safely combine results after both threads finish via join()
Each WithdrawalTask thread just stores 'amount' as 'result' rather than touching the shared balance;
the main thread waits for both via join() and then safely totals/applies the withdrawals itself.
15. Answer: B — It makes the calling (main) thread wait until t1 has finished executing before
proceeding
join() causes the main thread to pause and wait until t1 has completed, ensuring its result is ready
before the main thread uses it.
16. Answer: B — To check whether a thread has fully finished running, acting as a check-
valve before the main program touches shared attributes
isAlive() is used as a check-valve: the main program loops while [Link]() is true, waiting for
thread 1 to fully finish before letting thread 2 start, avoiding overlapping access.
17. Answer: B — Because the loop deliberately busy-waits, blocking the main thread from
calling [Link]() until t1 has terminated
The empty while([Link]()) loop keeps the main thread busy-waiting until t1 is no longer alive, and
only then is [Link]() called — preventing both threads from withdrawing concurrently.
18. Answer: B — To pause execution for 500 milliseconds between each text toggle, creating
the flashing effect
[Link](500) pauses the thread for 500 milliseconds on each loop iteration, which is what
produces the visible flashing toggle effect on the label.
19. Answer: B — Because sleep() is designed to cancel its current operation and return
immediately (via the exception) if the thread is interrupted while sleeping
Methods like sleep() that throw InterruptedException are designed to cancel their current operation
and return immediately when an interrupt is received.
20. Answer: B — The main thread called [Link](), which threw an
InterruptedException inside the worker's [Link](2000) call
[Link]() sends an interrupt signal; since the worker is sleeping inside [Link](2000),
this throws InterruptedException, which is caught, causing the run() method to print the message
and exit the loop.
21. Answer: B — wait() and notify()/notifyAll()
wait() tells the calling thread to release the monitor and sleep until another thread on the same
object calls notify() or notifyAll(), which wakes it back up.
22. Answer: B — Because they operate on an object's monitor/lock, which a thread must
hold in order to safely call them
wait(), notify(), and notifyAll() belong to the Object class and operate on the object's monitor, so they
must be called while holding the lock, i.e. inside synchronized code.
23. Answer: A — The consumer can read the same value multiple times before the producer
produces a new one, or values can be skipped entirely
Without coordination, the consumer's get() can run several times before put() updates n again (or
vice versa), leading to duplicated or skipped values, as seen with repeated 'Got: 1' lines in the
output.
24. Answer: B — It ensures the producer waits if a value hasn't been consumed yet, and the
consumer waits if no new value has been produced yet, alternating Put/Got pairs correctly
valueSet tracks whether a produced value is waiting to be consumed; put() waits if valueSet is true
(full), and get() waits if valueSet is false (empty), with notify() waking the other side, producing the
clean alternating Put/Got output.
25. Answer: B — A situation where two or more threads are permanently blocked because
each is waiting for the other to release a required lock
Deadlock occurs when two or more threads are permanently blocked, each waiting for a lock held by
the other, creating a circular wait that freezes the application.
26. Answer: A — The main thread holds the lock on object 'a' and tries to call [Link](), while
the racing thread holds the lock on object 'b' and tries to call [Link]() — each waits on a lock
the other holds
MainThread enters [Link]() (locking a) and then needs [Link]() (locking b); meanwhile RacingThread
enters [Link]() (locking b) and needs [Link]() (locking a). Each thread holds one lock while waiting on
the other, forming a circular wait — a classic deadlock.
27. Answer: A — Mutual Exclusion, Hold and Wait, No Preemption, Circular Wait
Deadlock requires all four conditions — Mutual Exclusion, Hold and Wait, No Preemption, and
Circular Wait — to occur at the same time; eliminating any one of them prevents deadlock.
28. Answer: B — By controlling which thread holds a resource versus which thread must
wait, making the lock/wait relationship explicit and manageable rather than an uncontrolled
circular dependency
Locks manage access to shared resources, explicitly marking what is 'Locked' versus 'Waiting' for
each thread, which is the mechanism Java provides to control and prevent uncontrolled circular
waits that cause deadlock.
29. Answer: B — start() launches a brand-new thread and invokes run() concurrently, while
calling run() directly executes sequentially with no new thread
As shown in the 'Execution Logic: start() vs run()' diagram, start() launches a new thread that calls
run() concurrently, whereas calling run() directly results in sequential execution on the existing
thread.

You might also like