14 KiB
What is the difference between the Ready to Run and Running states?
🚦
- Ready to Run: The thread is in the Runnable pool and waiting for a processor to become available.
- Running: The thread's code is actively being executed by a processor. %%% How many threads can be in the Running state at any given time?
💻
- On a single-processor computer: At most one thread.
- On a multi-processor computer: At most one thread per processor. %%%
What operation moves a thread from the Born state to the Runnable state?
🐣 Invoking the start() method.
%%%
Define the following transitions between Ready to Run and Running:
- Dispatched
- Yield
- Preempted / Timeslice Expired
🔄
- Dispatched: The scheduler selects a "Ready" thread to start running.
- Yield: The thread voluntarily gives up the processor to let others run.
- Preempted: The OS forces the thread to stop running (often because its time is up or a higher priority thread arrived). %%% What does it mean to model a thread's lifecycle as a Finite State Machine (FSM)?
🤖 It means representing the various states a thread can occupy and the specific operations (transitions) that cause it to move from one state to another. %%%
When does a thread transition into the Dead state?
💀 When its run() method terminates, either by returning normally or by throwing an uncaught exception.
%%%
What causes a thread to move into the Sleeping state, and how does it leave?
😴
- Entering: The thread invokes the
sleep()method. - Leaving: It remains blocked until the specified sleep time elapses or it is interrupted. %%%
How do the wait() and notify() methods interact?
🛑
wait(): Causes the current thread to block and enter the Waiting state.notify()/notifyAll(): Invoked by another thread to move the waiting thread(s) back to the Runnable state. %%% What happens to a thread's state during an I/O operation (like reading a file)?
📥 The thread enters the I/O blocked state when the request is made and only becomes Runnable again once the I/O is completed. %%%
If a method call (like sleep or wait) causes a thread to relinquish the processor, when does that method return?
⏳ The method does not return until the thread is rescheduled and is back in the Running state. %%% In what context are methods always executed?
🧵 Methods are always executed in the invoking thread's context. A thread can only invoke a method when it is currently in the Running state. %%%
What are the three named priority constants defined in the Java Thread class?
Thread.MAX_PRIORITY(Value: 10)Thread.NORM_PRIORITY(Value: 5)Thread.MIN_PRIORITY(Value: 1) %%% What is the valid integer range for a thread's priority?
🔢 It must be an integer between 1 and 10, inclusive. %%% How is a newly created thread's priority determined by default?
👪 It is set equal to the priority of the thread that created it. %%% Which methods are used to modify or check a thread's priority at runtime?
🛠️
setPriority(int): Sets the priority to a specific value.getPriority(): Returns the current priority of the thread. %%%
In a standard priority-based scheduler, which threads are normally selected to enter the Running state?
🚀 The threads in the Runnable state with the highest priorities. %%%
What are three ways a thread voluntarily relinquishes the processor?
🙋
Thread.yield(): Explicitly giving up the processor.Thread.sleep(): Ceasing execution for a specific time.Object.wait(): Waiting for a notification from another thread. %%% What two events cause a thread to terminate and release the processor permanently?
🏁
- The
run()method finishes its execution. - An exception is thrown that propagates beyond the
run()method. %%% What is Preemptive, Priority-Based Scheduling?
🥊 A scheduling policy where a lower-priority thread is forced to stop running (preempted) as soon as a higher-priority thread becomes ready to run.
%%% How does a timeslice affect thread execution in supported systems?
⏳ If timeslicing is supported, a thread will relinquish the processor if its allotted time interval (timeslice) expires, allowing other threads of equal priority a chance to run. %%% Why does the JVM rely on the preemption of lower-priority threads?
🚨 To ensure that high-priority threads that need processor time urgently (e.g., for real-time tasks) receive it immediately without waiting for others to finish. %%%
In a JVM without timeslicing, how do two equal-priority threads (t_1 and t_2) share a single processor?
🧵 t_1 will run until it terminates, relinquishes the processor voluntarily, or is preempted by a higher-priority thread. t_2 will not start until t_1 is no longer eligible to run.
%%%
How does Timeslicing change the execution of equal-priority threads?
🔄 The scheduler uses a Round-Robin approach, allowing each thread to run for a fixed amount of time before switching to the next thread of the same priority. %%% Does the Java specification require timeslicing for equal-priority threads?
📜 No. Either approach (running to completion or timeslicing) is permitted by the Java specification.
%%%
If t_1 and t_2 are high priority and t_3 is low priority, when will t_3 get to run in a timesliced system?
⏳ Only when both t_1 and $t_2$ are no longer eligible to run (e.g., they terminate or block). The JVM will not schedule lower-priority threads while higher ones are Runnable.
%%%
What is Bounded Priority Inversion?
📉 It occurs when a high-priority thread is forced to wait for a low-priority thread to release a lock. It is "bounded" because the delay is limited to the time it takes the low-priority thread to finish its critical section. %%%
How does Unbounded Priority Inversion differ from the bounded version?
🌪️ It happens when a medium-priority thread preempts the low-priority thread that holds the lock. Since the high-priority thread is waiting for the lock, and the low-priority thread can't run to release it because of the medium thread, the high-priority thread is blocked for an indeterminate (unbounded) amount of time. %%%
Why is disabling preemption while a low-priority thread is in a critical section considered a poor solution?
🚫 Because it stops all other high-priority threads from running, even those that have nothing to do with the critical section or the lock in question. %%% What are the two common protocols used to solve the Priority Inversion problem?
🛡️
- Priority Inheritance Protocol: The low-priority thread "inherits" the high-priority of the thread it is blocking until it releases the lock.
- Priority Ceiling (Priority Protect) Protocol: The priority of the thread holding the lock is elevated to a predefined "ceiling" value (the highest priority of any thread that might ever need that lock). %%% Which two system conditions must exist for Unbounded Priority Inversion to be a risk?
⚙️
- Priority-based preemptive scheduling.
- A mechanism for locking/mutual exclusion to protect critical sections. %%%
How does the Priority Inheritance Protocol protect against medium-priority threads?
🛡️ When a high-priority thread blocks on a lock held by a low-priority thread, the low-priority thread's priority is raised to match the high-priority thread. This prevents medium-priority threads from preempting it and causing unbounded delay. %%%
When is a thread's priority restored to its original value under the Priority Inheritance Protocol?
🔙 As soon as the thread leaves the critical section and releases the lock. %%% What determines the current priority of a thread holding a lock under Priority Inheritance?
📈 It is the higher of:
- Its own assigned priority.
- The priority of the highest-priority thread currently blocked and waiting for that same lock. %%% How does a Deadlock occur in a system with shared resources?
🔄 It arises when two or more threads are stuck in a circular wait: Thread A holds Resource 1 and waits for Resource 2, while Thread B holds Resource 2 and waits for Resource 1.
%%% What is the difference between Deadlock Detection and Deadlock Prevention?
🔍
- Detection: Allowing deadlocks to happen but using tools (like watchdog timers or request graph analysis) to find and reset the system.
- Prevention: Using a strict policy, such as requesting resources in the same order, to ensure a deadlock can never physically occur. %%% Why is "requesting resources in the same order" considered a Prevention strategy?
📏 It removes the possibility of a circular wait. If everyone agrees to lock Resource A before Resource B, you can never have a situation where two threads are waiting on each other. %%% How does a Watchdog Timer help handle deadlocks?
🐕 It is a timer that must be reset periodically by the software; if a deadlock occurs and the software stops responding, the timer expires and automatically resets the system. %%%
What is the Ceiling Priority of a lock?
🔝 It is a priority assigned to a lock when it is created that is at least as high as the priority of the highest-priority thread that can ever acquire it. %%% How does the Priority Ceiling Protocol handle preemption?
🛡️ Only threads with a priority higher than the current global ceiling priority can preempt a thread that is executing within a critical section. %%%
How does PCP prevent Deadlocks?
🚫 By design, the protocol ensures the system is deadlock-free because it coordinates lock acquisition in a way that prevents circular wait conditions from ever forming. %%% In the Priority Ceiling Protocol, why might a high-priority thread be blocked even if a lock is free?
🚦 If the thread's priority is not higher than the current global ceiling priority, it is blocked from acquiring the lock to ensure that lower-priority threads currently holding other resources can finish without interference. %%% What are the main differences between Priority Inheritance and Priority Ceiling regarding configuration?
⚙️
- Priority Inheritance: Managed transparently by the system; no programmer setup is required.
- Priority Ceiling: Requires the programmer to manually configure the priority ceilings for every lock. %%% How do the two protocols differ in when they "promote" a thread's priority?
📈
- Priority Inheritance: Promotion occurs only when a higher-priority thread actually attempts to acquire the lock.
- Priority Ceiling: Promotion is associated with the lock itself; the priority is effectively managed as soon as any thread interacts with the protected critical section. %%% Does Java currently support the Priority Ceiling Protocol?
📜 No. The priority ceiling protocol is not currently supported by Java; Java implementations typically use Priority Inheritance. %%%
What are Green Threads?
🌳 A thread model where the JVM is completely responsible for thread management (stack, PC, bookkeeping). The underlying operating system is unaware of these threads. %%% How does the OS view a Java process using Green Threads?
👁️ The OS sees the entire JVM as a single process with a single thread. All context switching between Java threads happens internally within the JVM without OS system calls.
%%% What are the scheduling characteristics of most Green Thread implementations?
⚖️ They typically support priority-based, preemptive scheduling, but most do not support timeslicing. They often use priority inheritance to prevent inversion. %%% What defines the Native Threads model?
🖥️ Java threads are mapped directly to the threads supported by the host Operating System. The OS, not the JVM, is responsible for scheduling the threads. %%% How are Java priorities handled in Windows Native Threads?
🗺️ There is a one-to-one mapping between Java and Win-32 threads, but because Windows has fewer priority levels, the 10 Java priorities are mapped onto 6 Win-32 priorities. %%% Why might equal-priority threads behave differently on Windows vs. early Unix Green Threads?
⏳ In Windows Native Threads, equal-priority threads timeslice, whereas many Green Thread implementations do not support timeslicing (one runs until it blocks or terminates). %%% In Embedded Systems, how is Java thread scheduling typically determined?
📟 Java threads are usually mapped to the native threads/tasks of the Real-Time Operating System (RTOS). Therefore, Java thread scheduling is equivalent to RTOS scheduling. %%% Why is OS support (Native Threads) required for true multi-processor concurrency?
🚀 Because Green Threads are managed inside a single OS process, they cannot be distributed across multiple physical CPUs by the OS. Only Native Threads allow the OS to run different Java threads on different cores simultaneously.