First, we need to define a task (for example, processing a data item), and then create multiple threads to perform these tasks in parallel.
1. Use multithreading to process multiple data
Suppose we have a list of integers and we want to perform some operation on each integer in the list in parallel (for example, compute squared).
(1)Define tasks: We can create an implementationRunnable
Interface class to represent tasks.
(2)Create thread:For each data item in the list, we create a new thread to perform the task.
(3)Start the thread: calling threadstart()
Method to start the thread.
(4)Wait for the thread to complete: We can use it if neededjoin()
Method to wait for all threads to complete.
Here is a complete code example:
import ; import ; public class MultiDataProcessingExample { // Define the task: calculate the square of integers static class SquareTask implements Runnable { private int number; public SquareTask(int number) { = number; } @Override public void run() { int square = number * number; ("The square of " + number + " is " + square); } } public static void main(String[] args) { // Create an integer list List<Integer> numbers = new ArrayList<>(); for (int i = 1; i <= 10; i++) { (i); } // Create a thread for each integer to calculate the square List<Thread> threads = new ArrayList<>(); for (int number : numbers) { Thread thread = new Thread(new SquareTask(number)); (thread); (); // Start the thread } // Wait for all threads to complete (optional) for (Thread thread : threads) { try { (); } catch (InterruptedException e) { (); } } // All threads have been completed, continue with other operations of the main thread (if any) ("All threads have finished."); } }
In this example, we define aSquareTask
Class to implementRunnable
Interface, this class represents the task of calculating integer squares. Then, inmain
In the method, we create a list of integers from 1 to 10, and create a new thread for each integer in the list to executeSquareTask
. Finally, we start all the threads and (optionally) wait for them to complete.
2. Use JavaExecutorService and Callable interface to handle multiple data examples
Here is a Java-userExecutorService
andCallable
An example of an interface to process multiple data. In this example, we will useExecutorService
to manage thread pools and useFuture
to get the results of each task.
First, we define an implementationCallable
The task of the interface, which returns the calculated result. Then, we create aExecutorService
, submit multiple tasks, and useFuture
Objects to collect results.
import ; import ; import .*; public class MultiDataProcessingWithExecutorService { // Define the task: calculate the square of an integer and return the result static class SquareCallable implements Callable<Integer> { private final int number; public SquareCallable(int number) { = number; } @Override public Integer call() throws Exception { int square = number * number; return square; } } public static void main(String[] args) throws ExecutionException, InterruptedException { // Create an integer list List<Integer> numbers = new ArrayList<>(); for (int i = 1; i <= 10; i++) { (i); } // Create a fixed-size thread pool ExecutorService executorService = (5); // Submit the task and get the Future list List<Future<Integer>> futures = new ArrayList<>(); for (int number : numbers) { Future<Integer> future = (new SquareCallable(number)); (future); } // Get and print the results of each task for (Future<Integer> future : futures) { // Note: the get() method will block until the task is completed Integer result = (); ("The square of " + ((future) + 1) + " is " + result); } // Close the thread pool (); // Wait for all tasks to complete (if not completed) try { // Wait for the task in the thread pool to complete within the specified time if (!(60, )) { // The thread pool does not terminate within a given time, we can choose to cancel it (); } } catch (InterruptedException ie) { // The current thread is interrupted while waiting (); ().interrupt(); } // All threads have been completed, continue with other operations of the main thread (if any) ("All threads have finished."); } }
In this example, we use (5) to create a thread pool with 5 threads. We then submit a SquareCallable task for each integer in the list and save the returned Future object in the list. By calling the() method, we can get the results of each task and print it out. Finally, we close the thread pool and wait for all tasks to complete.
Using ExecutorService and Callable is usually more convenient and flexible than using Thread and Runnable directly, because ExecutorService provides management of thread pools, while Callable allows tasks to return results.
3. Use concurrent programming to process multiple data simultaneously
In Java concurrent programming, a common approach is to use the ExecutorService and Callable interfaces to process multiple data simultaneously and collect results. Here is a complete code example showing how to use ExecutorService and Future to process each element in a list of integers simultaneously and collect their squared results:
import ; import ; import .*; public class ConcurrentSquareCalculator { // Define a Callable task to calculate squared static class SquareCallable implements Callable<Integer> { private final int number; public SquareCallable(int number) { = number; } @Override public Integer call() throws Exception { return number * number; } } public static void main(String[] args) throws ExecutionException, InterruptedException { // Create an integer list List<Integer> numbers = new ArrayList<>(); for (int i = 1; i <= 10; i++) { (i); } // Create a fixed-size thread pool ExecutorService executorService = (5); // Submit tasks and collect Future objects List<Future<Integer>> futures = new ArrayList<>(); for (int number : numbers) { Future<Integer> future = (new SquareCallable(number)); (future); } // Wait for all tasks to complete and collect results List<Integer> squares = new ArrayList<>(); for (Future<Integer> future : futures) { // Note: the get() method will block until the task is completed Integer square = (); (square); } // Print the result for (int i = 0; i < (); i++) { ("The square of " + (i) + " is " + (i)); } // Close the thread pool (); // Wait for all tasks in the thread pool to be executed try { if (!(60, )) { // The thread pool does not terminate within a given time, you can choose to cancel it (); } } catch (InterruptedException ie) { // The current thread is interrupted while waiting (); ().interrupt(); } // All threads have been completed, continue with other operations of the main thread (if any) ("All threads have finished."); } }
In this example, we create a SquareCallable class that implements the Callable<Integer> interface to calculate the square of an integer. Then, in the main method, we create a list of integers from 1 to 10 and create a fixed thread pool of size 5.
Next, we iterate through the list of integers, create a SquareCallable task for each integer, and submit it to the thread pool for execution. The thread pool manages the execution of these tasks and returns Future objects that can be used to obtain the results of the tasks.
We collect these Future objects into a list, iterate through this list, use the get() method to get the results of each task, and collect the results into another list. Note that the get() method blocks until the task completes and returns the result.
Finally, we print out the squared result of each original number and close the thread pool. We also use the awaitTermination method to wait for all tasks in the thread pool to complete execution to ensure that all resources are released correctly.
4. Use asynchronous programming to process multiple data simultaneously
One common way to asynchronously program in Java to process multiple data simultaneously is to use CompleteFuture. CompleteFuture is a powerful class introduced in Java 8, which represents the result of an asynchronous calculation. Here is an example of using CompletableFuture to process multiple data simultaneously:
import ; import ; import ; import ; import ; public class AsyncProcessingExample { // A method is used to simulate calculation squared public static int square(int number) { // Assume there are some calculations here try { // Simulation time-consuming operation (1000); } catch (InterruptedException e) { ().interrupt(); } return number * number; } public static void main(String[] args) throws ExecutionException, InterruptedException { // Create an integer list List<Integer> numbers = (1, 2, 3, 4, 5); // Use stream and to process each number asynchronously List<CompletableFuture<Integer>> futures = () .map(number -> (() -> square(number))) .collect(()); // Use to wait for all futures to complete CompletableFuture<Void> allFutures = ((new CompletableFuture[0])); // Wait for all tasks to complete (); // Collect results List<Integer> squares = () .map(future -> { try { return (); // This may throw an exception, but in this example we assume there is no exception } catch (InterruptedException | ExecutionException e) { throw new IllegalStateException(e); } }) .collect(()); // Print the result (::println); } }
In this example, we first create a list containing integers. We then use Java 8's Stream API to process each number in the list asynchronously. The supplyAsync method returns a CompletableFuture, which represents the result of an asynchronous calculation.
We collect all the CompletableFutures into a list and use to wait for all the Futures to complete. The allOf method returns a new CompletableFuture<Void>, which is completed when all given Futures are completed.
Then, we call the join() method to wait for all Futures to complete. The join() method blocks the current thread until Future completes.
Finally, we use the stream again to get the results from each CompletableFuture and collect them into a new list. We use the get() method to get the result, but please note that if Future's calculation throws an exception, the get() method will also throw an exception. In this example, we assume there are no exceptions, but in practical applications, you should handle these exceptions properly.
Finally, we print out the calculated square number.
This is the introduction to this article about the common methods of Java processing multiple data at the same time. For more related Java processing data content, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!