Multiple methods of Java multithreading implementation
In modern programming, multithreading is a key technology that enables programs to perform multiple tasks at the same time, improving the efficiency and performance of the system. In Java, there are many ways to implement multi-threading, each with its unique application scenarios and advantages and disadvantages. This article will introduce several common Java multithreading methods in detail, including the basic Thread class, Runnable interface, advanced thread pool, concurrency tool classes, asynchronous programming and new concurrency features, to help you deeply understand the different implementation methods of multithreading.
1. Java multithreading basic concept
What is a thread?
Threads are the smallest execution unit in the operating system. It contains the order of program execution, call stack, register and other resources. A process can contain multiple threads, each thread shares the process's resources (such as memory, file handles, etc.), but has its own independent execution path.
Why use multithreading?
Multithreading allows programs to execute multiple tasks at the same time, thereby maximizing the ability of multi-core processors and improving program execution efficiency. For example, a GUI application can process user input in one thread while performing time-consuming calculations in another thread to avoid interface lag.
Threading model in Java
Threads in Java are implemented based on native threads of the operating system, and Java providesClass and
Interface to support multi-threaded programming. Java 5 and later introduced more advanced concurrency tools such as the Executor framework, concurrent tool classes and asynchronous programming models, which greatly simplify the complexity of multithreaded programming.
2. Inherit the Thread class
One of the most basic ways to implement multithreading is inheritanceThread
kind. Through inheritanceThread
class, you can use the class directlystart()
Method to start the thread.
Implementation method
class MyThread extends Thread { @Override public void run() { // Code executed by thread ("Thread is running..."); } } public class Main { public static void main(String[] args) { MyThread thread = new MyThread(); (); // Start the thread } }
run()
The method contains the execution logic of the thread.start()
The method will create a new thread and will be called automaticallyrun()
method.
Applicable scenarios
inheritThread
Class methods are suitable for simple multithreaded implementations, especially when each thread is an independent task.
Pros and cons
-
advantage:
- Simple implementation, direct inheritance
Thread
Class and rewriterun()
Just the method.
- Simple implementation, direct inheritance
-
shortcoming:
- Java only allows single inheritance. If other classes have been inherited, it cannot be inherited.
Thread
kind. - Not suitable for complex multithreaded management scenarios, such as thread pool management.
- Java only allows single inheritance. If other classes have been inherited, it cannot be inherited.
3. Implement the Runnable interface
Another basic method to implement multithreading is to implementRunnable
interface. and inheritanceThread
Different classes, implementationRunnable
The interface is more flexible because it allows classes to inherit other classes.
Implementation method
class MyRunnable implements Runnable { @Override public void run() { // Code executed by thread ("Runnable is running..."); } } public class Main { public static void main(String[] args) { MyRunnable runnable = new MyRunnable(); Thread thread = new Thread(runnable); (); // Start the thread } }
Applicable scenarios
accomplishRunnable
Interfaces are suitable for scenarios where multi-threading functionality is required but do not want to be limited by the Java single inheritance mechanism. It is more suitable for designs that separate business logic from thread control.
Pros and cons
-
advantage:
- Multithreading can be implemented through implementation interfaces, and is not restricted by the Java single inheritance mechanism.
- The code is more reusable, and business logic and thread control are separated.
-
shortcoming:
- and inheritance
Thread
Compared to the class, the startup thread needs to be created.Thread
Object.
- and inheritance
4. Callable and Future
The run() method of the Runnable interface cannot return the result and cannot throw an exception. If you need a thread to return a result or throw an exception, you can use the Callable interface in conjunction with Future.
Introducing the Callable interface
The Callable interface is a more powerful interface introduced by Java 5. It allows the result to be returned after the task is executed and exceptions can be thrown.
import ; import ; import ; class MyCallable implements Callable<Integer> { @Override public Integer call() throws Exception { // Code executed by thread return 123; } } public class Main { public static void main(String[] args) { MyCallable callable = new MyCallable(); FutureTask<Integer> futureTask = new FutureTask<>(callable); Thread thread = new Thread(futureTask); (); try { // Get the result returned by the thread Integer result = (); ("Thread result: " + result); } catch (InterruptedException | ExecutionException e) { (); } } }
The role and implementation of Future
Future
Interfaces are used to represent the results of asynchronous calculations. By callingget()
Method, you can wait for the calculation to complete and get the result.
Application scenarios
When the thread needs to return the calculation result, or an exception may be thrown during execution,Callable
andFuture
Ideal for you.
5. Use the Executor framework
Before Java 5, developers could only passThread
Class orRunnable
The interface manages threads manually. As concurrency demand grows, Java 5 introducesExecutor
Framework greatly simplifies thread management.
The concept of thread pool
A thread pool is a set of reusable threads. Through thread pooling, frequent creation and destruction of threads can be avoided and performance can be improved. Thread pools can also help manage the number of concurrent threads and prevent excessive threads from causing system resources to be exhausted.
Use of Executors class
Executors
Classes provide multiple ways to create thread pools, e.g.newFixedThreadPool()
、newCachedThreadPool()
andnewSingleThreadExecutor()
。
import ; import ; public class Main { public static void main(String[] args) { ExecutorService executor = (3); for (int i = 0; i < 5; i++) { (new RunnableTask(i)); } (); } } class RunnableTask implements Runnable { private int taskId; public RunnableTask(int taskId) { = taskId; } @Override public void run() { ("Task ID: " + + " performed by " + ().getName()); } }
Custom thread pool
If you need more flexible thread pool configuration, you can useThreadPoolExecutor
Class custom thread pool.
import ; import ; import ; public class Main { public static void main(String[] args) { ThreadPoolExecutor executor = new ThreadPoolExecutor( 2, 4, 60, , new LinkedBlockingQueue<>(10)); for (int i = 0; i < 10; i++) { (new RunnableTask(i)); } (); } }
Applicable scenarios
Thread pools are suitable for high concurrency scenarios, and can effectively manage and reuse threads, avoiding the overhead of frequent creation and destruction of threads.
6. Use of concurrent tool classes
Java concurrency package () provides many tool classes for thread synchronization and coordination. The following are several commonly used tool classes.
CountDownLatch
CountDownLatch
Used for multiple threads to wait for an event to complete.
import ; public class Main { public static void main(String[] args) throws InterruptedException { CountDownLatch latch = new CountDownLatch(3); for (int i = 0; i < 3; i++) { new Thread(() -> { (().getName() + " is working..."); (); // Call countDown() after each thread is completed }).start(); } (); // Wait for all threads to complete ("All threads have finished."); } }
CyclicBarrier
CyclicBarrier
Used to wait for multiple threads to continue execution until all threads reach the Barrier.
import ; import ; public class Main { public static void main(String[] args) { CyclicBarrier barrier = new CyclicBarrier(3, () -> { ("All parties have arrived at the barrier, let's proceed."); }); for (int i = 0; i < 3; i++) { new Thread(() -> { (().getName() + " is waiting at the barrier."); try { (); } catch (InterruptedException | BrokenBarrierException e) { (); } (().getName() + " has crossed the barrier."); }).start(); } } }
Semaphore
Semaphore
Used to control the number of threads that access a specific resource simultaneously.
import ; public class Main { public static void main(String[] args) { Semaphore semaphore = new Semaphore(2); for (int i = 0; i < 5; i++) { new Thread(() -> { try { (); // Obtain a license (().getName() + " is performing a task."); (2000); (); // Release the license } catch (InterruptedException e) { (); } }).start(); } } }
Exchanger
Exchanger
Used to exchange data between two threads.
import ; public class Main { public static void main(String[] args) { Exchanger<String> exchanger = new Exchanger<>(); new Thread(() -> { try { String data = "Data from Thread A"; String receivedData = (data); ("Thread A received: " + receivedData); } catch (InterruptedException e) { (); } }).start(); new Thread(() -> { try { String data = "Data from Thread B"; String receivedData = (data); ("Thread B received: " + receivedData); } catch (InterruptedException e) { (); } }).start(); } }
Phaser
Phaser
andCyclicBarrier
Similar, but it is more flexible, allowing threads to participate dynamically or leave.
import ; public class Main { public static void main(String[] args) { Phaser phaser = new Phaser(3); for (int i = 0; i < 3; i++) { new Thread(() -> { (().getName() + " is in phase " + ()); (); // Arrive and wait for other threads }).start(); } (); // The main thread leaves, and other threads can continue ("Main thread is deregistered from the phaser."); } }
Applicable scenarios
These tool classes are suitable for scenarios where multiple threads work together, and can help developers simplify thread synchronization and coordination logic.
7. Use of Lock and Condition
Before Java 5, developers could only use itsynchronized
Keywords to implement thread synchronization. Java 5 has been introducedLock
The interface provides a more flexible locking mechanism.
ReentrantLock
ReentrantLock
yesLock
A commonly used implementation of the interface, supports the reentry lock feature, allowing threads to repeatedly acquire locks without deadlocks.
import ; import ; public class Main { private final Lock lock = new ReentrantLock(); public void performTask() { (); // Get the lock try { // Execute tasks (().getName() + " is performing a task."); } finally { (); // Release the lock } } public static void main(String[] args) { Main main = new Main(); for (int i = 0; i < 3; i++) { new Thread(main::performTask).start(); } } }
Condition
Condition
The interface provides a comparisonsynchronized
andwait/notify
A more flexible inter-thread communication method. passCondition
, more complex waiting/notification mode can be implemented.
import ; import ; import ; public class Main { private final Lock lock = new ReentrantLock(); private final Condition condition = (); public void performTask() throws InterruptedException { (); try { (().getName() + " is waiting."); (); // Wait for signal (().getName() + " is performing a task."); } finally { (); } } public void signalTask() { (); try { ("Signal to perform the task."); (); // Send signal } finally { (); } } public static void main(String[] args) throws InterruptedException { Main main = new Main(); new Thread(() -> { try { (); } catch (InterruptedException e) { (); } }).start(); (1000); new Thread(main::signalTask).start(); } }
Applicable scenarios
Lock
andCondition
Suitable for scenarios where more flexible thread control and communication is required, such as complex multithreaded synchronization, waiting and notification mechanisms.
8. Use the Fork/Join framework
Fork/Join
The framework was introduced in Java 7 and is used to execute tasks in parallel. It is a framework that supports work-stealing algorithms and is suitable for tasks that can be decomposed recursively.
ForkJoinPool and ForkJoinTask
ForkJoinPool
yesFork/Join
The core of the framework, responsible for managing threads and tasks.ForkJoinTask
is the base class for all tasks.
import ; import ; public class Main { public static void main(String[] args) { ForkJoinPool forkJoinPool = new ForkJoinPool(); long result = (new SumTask(1, 100)); ("Sum from 1 to 100: " + result); } } class SumTask extends RecursiveTask<Long> { private final int start; private final int end; public SumTask(int start, int end) { = start; = end; } @Override protected Long compute() { if (end - start <= 10) { long sum = 0; for (int i = start; i <= end; i++) { sum += i; } return sum; } else { int middle = (start + end) / 2; SumTask leftTask = new SumTask(start, middle); SumTask rightTask = new SumTask(middle + 1, end); (); // Perform subtasks return () + (); // Merge results } } }
Applicable scenarios
Fork/Join
The framework is suitable for recursive tasks that require parallel execution, such as processing and computing of large-scale data.
Pros and cons
-
advantage:
- Using work-stealing algorithms, the performance of multi-core processors can be maximized.
-
shortcoming:
- Suitable for specific types of tasks (such as tasks that can be broken down), not suitable for all scenarios.
9. Implement asynchronous programming using CompleteFuture
CompletableFuture
It is a class introduced in Java 8. It greatly simplifies asynchronous programming, allowing developers to write asynchronous code in a declarative manner.
Introduction to CompletableFuture
CompletableFuture
Supports creation, combination, and waiting for multiple asynchronous
Tasks support chain operations to make the code more concise.
import ; public class Main { public static void main(String[] args) throws InterruptedException { CompletableFuture<Void> future = (() -> { ("Async task is running."); }); (() -> ("Async task finished.")); (2000); // Wait for the asynchronous task to complete } }
Combining multiple asynchronous tasks
AvailablethenCombine
、thenAcceptBoth
The results of combining multiple asynchronous tasks are achieved by other methods.
import ; public class Main { public static void main(String[] args) throws InterruptedException { CompletableFuture<Integer> future1 = (() -> { return 10; }); CompletableFuture<Integer> future2 = (() -> { return 20; }); CompletableFuture<Integer> result = (future2, (x, y) -> x + y); (sum -> ("Sum: " + sum)); (2000); // Wait for the asynchronous task to complete } }
Process the results of asynchronous calculations
AvailablethenApply
、thenAccept
etc. Process the results of asynchronous calculations.
import ; public class Main { public static void main(String[] args) throws InterruptedException { CompletableFuture<Integer> future = (() -> { return 10; }); (result -> result * 2) .thenAccept(finalResult -> ("Final Result: " + finalResult)); (2000); // Wait for the asynchronous task to complete } }
Applicable scenarios
CompletableFuture
Suitable for scenarios where complex asynchronous processes are required, such as processing multiple independent tasks concurrently and combining the results into the final output.
in conclusion
Java provides a variety of methods to implement multi-threading, each method has its own specific application scenarios and advantages and disadvantages. In actual projects, developers should choose the appropriate implementation method according to their needs and follow the best practices of multi-threaded programming to ensure the stability and performance of the program.
By mastering these multi-threaded implementations, developers can develop efficient and reliable applications in high-concurrency environments. In future development, with the continuous improvement of hardware performance and the popularization of multi-core processors, mastering concurrent programming will become a necessary skill for every Java developer.
The above is the detailed content of n methods for Java to implement multi-threading. For more information about Java to implement multi-threading, please pay attention to my other related articles!