Java Thread to ExecutorService Opmize SwingUI
Why is thread optimization necessary?
Traditional writing methods can cause problems if not handled properly.
🏢 A vivid analogy: Imagine you're doing business at a bank.
Your previous approach (infinite multithreading): The bank didn't have permanent tellers.
Every time a customer came (clicked a button), the bank temporarily hired a new employee (new Thread()) to serve them.
After serving that customer, the employee was immediately dismissed (thread destroyed).
With continuous clicks or a slow network: If 100 customers arrived, or network congestion caused slow processing,
the bank lobby would instantly be overcrowded with 100 temporary employees.
Everyone would be crammed together, competing for space and air (CPU and memory resources),
ultimately causing the bank to crash. Optimized approach (single-thread pool): The bank assigned a dedicated,
permanent VIP teller (SingleThreadExecutor) to the lobby.
With continuous clicks or a slow network: Regardless of the number of customers,
they must all line up at the entrance (blocking queue). There's only one teller,
who processes transactions one by one in order. The lobby will never be overcrowded,
the bank will always operate smoothly, and it will never crash due to overcrowding.
Frequent Thread Creation and Destruction (A Fatal Performance Bottleneck):
Each call to the `setGitMessageEvent` method creates a new thread.
Consequence: Threads are a very resource-intensive component in the operating system.
Frequent thread creation and destruction causes the CPU to waste a significant amount of time on thread context switching and memory allocation instead of actually executing business logic.
If this event is triggered frequently (e.g., when a user types in an input box or clicks repeatedly), resource consumption will spike rapidly.
Let's take an example.
before
Is this threading approach efficient? No, it's inefficient and a classic example of a bad practice in Java programming. It not only has efficiency issues but also introduces code redundancy and potential UI freezes/crashes. The specific reasons are as follows: ❌ Problem 1. Frequent thread creation and destruction (a fatal efficiency bottleneck) In the `setGitMessageEvent` method, a new thread is created every time it's called. Consequence: Threads are very resource-intensive in the operating system. Frequent thread creation and destruction causes the CPU to waste a significant amount of time on thread context switching and memory allocation instead of actually executing business logic. If this event is triggered frequently (e.g., when a user types in an input box or clicks repeatedly), resource consumption will spike rapidly. 2. Severe Code Redundancy (Creating an Extra Thread Object): Consider these two lines of code: `javaGitMessageCommandThread gitMessageCommandThread = new GitMessageCommandThread(cmd);`
`new Thread(gitMessageCommandThread).start();`
Use code with caution. Problem: Your `GitMessageCommandThread` already inherits from `Thread`. It is itself a thread, and you've passed it as a `Runnable` to another `new Thread()`. Consequence: This is equivalent to creating an extra thread object unnecessarily, a low-level syntactic redundancy.
3. Thread Safety Risk (Illegal Multithreaded Operations on UI Components): In the `setMessage` method, there are `this.textArea.setText(s);` and `this.textField_2.setText(cmd);`. Problem: Judging from the component name, this is most likely a Java Swing or AWT-developed interface. In Java graphical interface development, it is absolutely forbidden to directly modify UI components in a child thread. Consequences: This can lead to strange refresh errors, flickering text, or even the entire software freezing and becoming unresponsive. 🛠️ The correct and efficient approach in actual development is to use a thread pool (ExecutorService) to reuse threads and combine it with SwingUtilities.invokeLater to safely update the interface.
opmize after
💡 Benefits of the optimization: Extremely high performance: Only one background thread is used, so no matter how many times you trigger an event, they will be queued and executed, completely eliminating the overhead of creating threads. Safe and stable: UI updates are wrapped in SwingUtilities.invokeLater, ensuring that the interface will never freeze or cause rendering conflicts. Concise code: Bulky inner classes have been removed, making the logic clear at a glance.
Explore More
› Java 21 Virtual Threads vs Java 17 Thread Pools in Swing Applications
› Building a Postman-Like API Client: Go Fyne vs Java Swing
› Oracle vs IBM: Who Would Have Been the Better Steward of Java?