The Java. util. Concurrent package in j2se 5.0 provides a new thread framework component that processes many low-level details related to creation, execution, and management threads. In this article, we will take a closer look at its important features.
If you use C, C ++, or a previous Java version for multi-threaded programming, you will know how troublesome it is to manage threads in code. In a single-threaded program, the bug that causes application failure in the code appears at the same point each time. However, in multi-threaded programs, failure occurs only when there are some causes. It is difficult to predict all the conditions that may cause application failure, so multi-threaded programming is challenging. Some programmers fundamentally avoid this challenge, while others-wise people who solve the problem-sit in front of their computers until the problem is solved.
The j2se 5.0 platform contains a new concurrency tool package. The classes in this package are used to create blocking for concurrent classes (concurrent Classe) or applications used in concurrent design ). The concurrency tool contains the following content:
• High-Performance and flexible Thread Pool
• Framework component for asynchronous transaction execution
• A set-Class Host (host) optimized for concurrent access)
This article introduces j2se 5.0 framework component classes and their important features. The download code in this article provides some simple and easy-to-use examples, which demonstrate all the new thread framework component classes. After reading the article, you can run these examples to better understand these features.
Executor framework component
The executor framework component provides a simple, standard, and extensible class that provides some useful functions. Without these functions, we need to implement them manually, it will be monotonous and difficult. This framework component standardizes the calling, scheduling, and execution operations. It supports Controlling Asynchronous transactions through a set of execution policies.
The executor interface executes committed transactions that can be run. It provides a way to separate the transaction commit from the transaction execution mechanism. Programmers usually use executor instead of explicit threads. The executor interface also provides synchronous and asynchronous execution of transactions.
For synchronous execution, run the following command:
Class MySynExecutor implements Executor{
public void execute(Runnable r) {
r.run();
}
} |
For Asynchronous execution, use the following command:
Class MyASynExecutor implements Executor{
public void execute(Runnable r) {
new Thread(r).start();
}
} |
Executorservice (Executor Service) Class
The executorservice class provides methods for managing the termination and tracking of one or more asynchronous transactions. The myexecutorservice. Java file in the Code download demonstrates the process of managing transaction termination. It initializes three thread pools and adds threads in sequence. When the number of threads reaches the thread pool size limit, it calls the shutdown method. After the shutdown () method is called, the thread pool no longer accepts the execution of new transactions. Wait 10 seconds later, the thread pool calls shutdownnow (). This method will do its best to end all running transactions. In this example, the application failed to terminate the running thread.
Scheduledexecutorservice (scheduling executor Service))
The scheduledexecutorservice class is my favorite class. It is very convenient to schedule those cyclically executed transactions, and the periodically executed transactions are especially useful for clearing jobs (such as clearing temporary files created by your application. The myscheduledexecutorservice. Java file in the downloaded code sends a "beep" every five seconds to demonstrate the scheduling process:
final Runnable beeper = new Runnable() {
public void run() { System.out.println("beep"); }
};
final ScheduledFuture beeperHandle =scheduler.scheduleAtFixedRate(beeper, 1, 5, SECONDS); |
Future and futuretask
In earlier versions of Java, it is very difficult to query the running thread status and return a value after the thread is executed. Because the run (run) method returns void, you must write a lot of code to return a value from the thread. Programmers who have used this method must understand their painful experiences.
You can use the future interface or the futuretask class to obtain a return value from the asynchronous thread. The future interface provides some methods to check whether the computing process is complete, to search the computing results, or to end the computing process. The futuretask class provides the basic implementation of the future interface method (implementation ). The results can be retrieved only after the computing process is completed. If the calculation process is not completed, the get method will be blocked ).
The mystringreverser. Java file in the downloaded code demonstrates the use of the futuretask class and provides an easy-to-understand example. It displays the submitted string from the back to the front at a speed of one character per second, and the main thread checks whether the transaction is completed:
while(!future.isDone()){
System.out.println("Task not yet completed.");
try{
Thread.currentThread().sleep(500);
}catch(InterruptedException ie){
System.out.println("Will check after 1/2 sec.");
}
} |
After the transaction is completed, use the get method to retrieve the result from the future object:
System. Out. println ("here is result..." + future. Get ());
Threadpoolexecutor (thread pool executor) |
With the threadpoolexecutor class, you can write your own server. This class provides many features for configuring and adjusting servers, similar to many large-scale enterprise-level EJB servers. Below are some of its configuration parameters:
• Core and maximum thread pool size
By setting corepoolsize and maximumpoolsize to the same value, you can create a fixed thread pool. By setting maximumpoolsize to a large value (such as integer. max_value), you can allow the thread pool to accommodate any number of concurrent transactions.
• Construct as needed
By default, threadpoolexecutor starts to establish and start the Core Thread only when new transactions are required. However, you can use prestartcorethread or prestartallcorethreads to dynamically reload it.
• Maintain the activity time
If the number of threads in the thread pool exceeds the corepoolsize, these threads will be terminated when their idle time exceeds KeepAliveTime.
• Queuing
Queuing follows the following rules:
• If the number of running threads is less than corepoolsize, executor will always add new threads instead of waiting in line.
• If corepoolsize or more threads are running, executor queues requests without adding new threads.
• If a request cannot participate in the queue, a new thread will be created unless the number of threads exceeds maximumpoolsize (when the number of threads exceeds, the transaction will be rejected ).
• Hook method
This class provides beforeexecute () and afterexecute () Hook methods, which are called before and after each transaction is executed. To use them, you must create a subclass of this class (because these methods are protected ).
In the downloaded code, mythreadpoolexecutor. Java provides detailed examples of monitoring multiple configuration parameters. You can find that the thread pool and queue size are changing as each transaction increases and completes. You can modify the settings in the code. Concurrent set
JDK 1.5 provides the following set implementations, which are designed for multithreading environments:
• Concurrenthashmap
• Copyonwritearraylist
• Copyonwritearrayset
The concurrenthashmap class provides complete thread-safe concurrency support for the expected concurrency that can be adjusted for retrieval and update. Copyonwritearrayset is a set of thread-safe variables. copyonarraylist is a thread-safe array list (arraylist) variable volume. Before modifying the original array or set, each of them copies the lower-layer array or set. The result is that the read speed is very fast, and the update speed is very slow.
The concurrent collection class provides snapshot-type data for iterator (iterative sub-) (even if the underlying data changes, it is not reflected in iterator ).
Synchronizer)
JDK 1.5 also provides some advanced classes, such as semaphore, countdownlatch, and cyclicbarrier, as well as an exchanger (switch) class for synchronization. This article does not describe the detailed analysis and usage information of these classes, because understanding them requires some theoretical background.
With these new classes, you can persuade technical superiors who are afraid of multithreading technology to develop multi-threaded applications.