Java multi-thread design mode (4) Thread Pool Mode

Source: Internet
Author: User

Preface:

Thread-Per-Message Pattern is a Thread that is allocated for each command or request for execution. It uses two different threads to implement "one end of the delegated message" and "one end of the executed message. The thread mode consists of three parts:

1. The Request participant (principal), that is, the message sender or command requester.

2. The Host participant receives the message request and is responsible for allocating a working thread to each message.

3. Worker participant. The thread that executes the task of the Request participant is started by the Host participant.

After a common method is called, you must wait until the method is fully executed before you can continue to perform the next operation. After the thread is used, you do not have to wait until the specific task is completed, you can immediately return to continue to perform the next operation.

Background:

In Thread-Per-Message Pattern, a Thread is generated for each request, and Thread startup takes a lot of time. Therefore, a Worker Thread is proposed, reuse started threads.

Thread Pool:

Worker Thread, also known as a Worker Thread or background Thread, is generally called a Thread pool. This mode is mainly used to start a certain number of worker threads in advance. When no job is requested, all worker threads will wait for new requests. Once a job arrives, it will immediately wake up a thread from the thread pool to execute the job, after the execution is complete, wait for the task pool's work request to arrive in the thread pool.

Task pool: It stores the collection of accepted requests. It can buffer received requests and set the size to indicate that the maximum number of requests can be accepted at the same time. This task pool is mainly accessed by the thread pool.

Thread Pool: this is the set of worker threads. You can set its size to provide concurrent processing workload. For the thread pool size, you can generate a certain number of threads in advance and dynamically increase or decrease the number of threads according to the actual situation. The larger the thread pool, the better, the time required for thread switching.

The data structure of the storage pool, which can be used as an array or a set. Vector is generally used in the collection class, which is thread-safe.

All participants of Worker Thread:

1. Client participant: the participant who sends the Request

2. Channel participants are responsible for caching Request requests, initializing startup threads, and allocating working threads.

3. Worker participant. The Worker thread that executes the Request

4. Request participants

Note: The Way to wait for the task pool inside the Worker thread is not empty is called forward wait.

The way in which the Channel thread provides Worker threads to determine whether the task pool is not empty is called reverse Waiting.

Thread Pool instance 1:

The synchronization method is used, and arrays are used as the data storage structure of the task pool. There are cache and request processing methods in the Channel. The producer and consumer modes are used to process the storage requests, and the reverse wait is used to determine the non-empty status of the task pool.

Channel participants:

Package whut. threadpool; // the producer and consumer mode is used. // The thread pool is generated to accept requests from the client thread, find a working thread that assigns this client request public class Channel {private static final int MAX_REQUEST = 100; // number of concurrent jobs, the number of client requests that can be accepted at the same time // The array is used to store requests. Each time a Request is added from the end of the array, the Request is removed from the beginning to process the private final Request [] requestQueue; // store the number of accepted client threads. private int tail; // the location where the Request is stored in the next time, private int head; // the location where the Request is obtained in the next time, private int count; // current request quantity private final WorkerThread [] threadPool; // stores the worker threads in the thread pool // uses arrays to store public Channel (int threads) {this. requestQueue = new Request [MAX_REQUEST]; this. head = 0; this. head = 0; this. count = 0; threadPool = new WorkerThread [threads]; // start the working thread for (int I = 0; I <threadPool. length; I ++) {threadPool [I] = new WorkerThread ("Worker-" + I, this) ;}} public void startWorkers () {for (int I = 0; I <threadPool. length; I ++) {threadPool [I]. start () ;}/// accept the client Request thread public synchronized void putRequest (request Request) {// when the number of requests is greater than or equal to the number of requests simultaneously, wait for while (count> = requestQueue. length) try {wait ();} catch (InterruptedException e) {} requestQueue [tail] = request; tail = (tail + 1) % requestQueue. length; count ++; policyall () ;}// process the client Request thread public synchronized Request takeRequest () {while (count <= 0) try {wait ();} catch (InterruptedException e) {} Request request = requestQueue [head]; head = (head + 1) % requestQueue. length; count --; policyall (); return request ;}}

Client request thread

Package whut. threadpool; import java. util. random; // public class ClientThread extends Thread {private final Channel; private static final Random random = new Random (); public ClientThread (String name, channel channel) {super (name); this. channel = channel;} public void run () {try {for (int I = 0; true; I ++) {Request request = new Request (getName (), I ); channel. putRequest (request); Thread. sleep (random. nextInt (1000) ;}} catch (InterruptedException e ){}}}

Worker thread:

Package whut. threadpool; // specific working Thread public class WorkerThread extends Thread {private final Channel channel; public WorkerThread (String name, Channel channel) {super (name); this. channel = channel;} public void run () {while (true) {Request request = channel. takeRequest (); request.exe cute ();}}}

Thread Pool instance 2:

The synchronization block is used to process and the Vector is used to store client requests. There are cache and request processing methods in the Channel. The producer and consumer modes are used to process the storage requests, and the forward wait is used to determine the non-empty status of the task pool.

This type of instance can be used for reference in the network ServerSocket processing mode for user requests, with good scalability and practicality.

The Vector is used for storage. The request is still added at the last position of each set, and the request is removed from the starting position for processing.

Channel participants:

Package whut. threadpool2; import java. util. vector;/** the main function is as follows: * 0. buffer the client request thread (using the producer and consumer mode) * 1. Store the client request thread * 2, initialize and start a certain number of threads * 3 and actively wake up some threads in the wait set in the task pool to execute the task */public class Channel {public final static int THREAD_COUNT = 4; public static void main (String [] args) {// defines two sets. One is for storing client requests, and the other is for storing threads using Vector and, that is, the number of threads in the thread pool // Vector is thread-safe. It implements the Collection and List // Vector classes to implement an array of objects that can grow. Like an array, // It contains components that can be accessed using integer indexes. However, the Vector size can be increased or reduced as needed. // you can add or remove items after creating a Vector. // The Collection mainly includes list-related sets and set-related sets. The Queue-related set // Note: Map is not a subclass of Collection and is a java. util. * same-level package Vector pool = new Vector (); // working thread, initially allocated a certain number of WorkerThread [] workers = new WorkerThread [THREAD_COUNT]; // initialize and start the working thread for (int I = 0; I <workers. length; I ++) {workers [I] = new WorkerThread (pool); workers [I]. start () ;}// receives a new task and stores it in the Vector Object task = new Object (); // The simulated task entity class // the specific work is omitted here // in network programming, ServerSocket is used here. accept accepts a Socket to wake up the thread // when a specific request reaches synchronized (pool) {pool. add (pool. size (), task); pool. yyall (); // notify all threads waiting in the pool wait set to wake up a thread for processing} // note the preceding steps to add the task pool request and the notification thread, all can be implemented in the worker thread. // you only need to define this method as static, use a synchronization block in the method body, and the shared thread pool is also static. // The following step, you can have a thread for (int I = 0; I <workers. length; I ++) {workers [I]. interrupt ();}}}

Worker thread:

Package whut. threadpool2; import java. util. list; public class WorkerThread extends Thread {private List pool; // task request pool private static int fileCompressed = 0; // public WorkerThread (List pool) shared by all instances {this. pool = pool;} // use static synchronized as the entire synchronized class method. You can only operate this class one time. This method is private static synchronized void incrementFilesCompressed () {fileCompressed ++ ;} public void run () {// ensure infinite loop while (true) {// share mutex to access pool variable synchronized (pool) {// In the multi-threaded design mode, the // Guarded Suspension Pattern is used. The alert condition is that the pool is not empty. Otherwise, the while (pool. isEmpty () {try {pool. wait (); // wait until the wait set enters the pool and releases the pool lock} catch (InterruptedException e) {}}// when the thread is awakened, you need to re-obtain the pool lock, // continue to execute the remaining work in the synchronized code block again. // when it is not empty, continue to judge whether it is empty. If it is not empty, then, the jump out of the loop // you must first remove a task from the task pool for execution. You can add the task from the end and remove the pool from the start. remove (0); // get the task in the task pool and perform conversion} // the specific work to be processed by the thread }}}


This article from the "dream in the cloud" blog, please be sure to keep this source http://computerdragon.blog.51cto.com/6235984/1205324

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.