如何切换线程池创建的线程?实现线程轮流打印模拟需求
Got it, let's break down how to solve this problem. You want a thread pool where only one thread prints at any given time—after it finishes printing, it waits up, and a random other thread grabs the lock to print next. This loops until your specific condition is met. Let's walk through implementations in two common languages, since the core logic translates across most platforms.
Core Logic Overview
The key here is using a shared lock to enforce mutual exclusion (only one thread prints at a time). To get random thread selection after each print, we rely on non-fair lock competition—when the lock is released, all waiting threads race to grab it, which effectively gives us random selection. We also need a shared condition flag to stop the loop once your target is met.
Java Implementation
Java's ExecutorService makes thread pool management straightforward, and ReentrantLock gives us the locking control we need:
import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.locks.ReentrantLock; public class RandomPrintThreadPool { // Shared lock to enforce single-thread printing private static final ReentrantLock printLock = new ReentrantLock(); // End condition: stop after 10 prints (adjust this to your needs) private static int printCounter = 0; private static final int MAX_PRINTS = 10; public static void main(String[] args) { // Create a thread pool with 5 worker threads ExecutorService threadPool = Executors.newFixedThreadPool(5); // Submit 5 print tasks to the pool for (int i = 0; i < 5; i++) { final int threadId = i + 1; threadPool.submit(() -> { while (true) { printLock.lock(); try { // Check if we've met the end condition if (printCounter >= MAX_PRINTS) { break; } // Execute the print operation System.out.printf("Thread %d is printing...%n", threadId); printCounter++; // Simulate time taken to print Thread.sleep(500); } catch (InterruptedException e) { // Restore interrupt status if interrupted Thread.currentThread().interrupt(); break; } finally { // Release the lock so other threads can compete printLock.unlock(); } // Wait a short time before trying to grab the lock again // Prevents the same thread from immediately re-locking try { Thread.sleep(100); } catch (InterruptedException e) { Thread.currentThread().interrupt(); break; } } }); } // Shutdown the pool once all tasks complete threadPool.shutdown(); } }
Key Notes for Java Version:
- Non-Fair Lock: The default
ReentrantLockis non-fair, meaning threads don't queue up in order. This is what gives us the "random thread selection" behavior when the lock is released. If you usenew ReentrantLock(true)(fair lock), threads will print in the order they waited, which isn't what you want here. - End Condition Safety: We check
printCounterinside the locked block to avoid race conditions where multiple threads might pass the check before the counter is updated. - Thread Interruption Handling: We properly handle interrupts so threads can exit cleanly if needed.
Python Implementation
For Python, we'll use ThreadPoolExecutor from the concurrent.futures module, paired with a standard threading.Lock:
import threading from concurrent.futures import ThreadPoolExecutor import time import random # Shared lock for print synchronization print_lock = threading.Lock() # End condition: stop after 10 prints print_counter = 0 MAX_PRINTS = 10 def print_task(thread_id): global print_counter while True: with print_lock: if print_counter >= MAX_PRINTS: break # Execute print operation print(f"Thread {thread_id} is printing...") print_counter += 1 # Simulate print time time.sleep(0.5) # Wait a random short time before re-competing for the lock # Ensures the same thread doesn't immediately re-grab the lock time.sleep(random.uniform(0.1, 0.3)) if __name__ == "__main__": # Create a thread pool with 5 workers with ThreadPoolExecutor(max_workers=5) as executor: # Submit tasks for each thread for thread_id in range(1, 6): executor.submit(print_task, thread_id)
Key Notes for Python Version:
withStatement for Locks: Usingwith print_lockautomatically handles locking and unlocking, even if an error occurs—safer than manualacquire()/release()calls.- Random Wait Time: Adding a random sleep after printing ensures the current thread doesn't immediately jump back into the lock competition, making it more likely another thread gets picked next.
内容的提问来源于stack exchange,提问作者Piyush Chandra

