Java multi-thread programming practices

Source: Internet
Author: User
Java multi-thread programming practices-general Linux technology-Linux programming and kernel information. The following is a detailed description. Java 5 adds a new class library concurrency set Java. util. concurrent, which provides a wide range of API multi-threaded programming for concurrent programs, making java 5 easier and more flexible. This article uses a network server model to implement Java 5's multi-threaded programming. This model uses the thread pool in Java 5, blocks the queue, and reentrant locks, and implements Callable, future and Other interfaces, and use another new feature of Java 5 generic.

Introduction

This article will implement a network server model. Once a client connects to the server, a new thread is started to serve the connection, and the service content is to deliver some character information to the client. A typical network server model is as follows:

1. Create a listening port.

2. New connections are found, connections are accepted, threads are started, and service threads are executed. 3. After the service is completed, close the thread.

This model runs well in most cases, but it needs to process user requests frequently. When the service required for each request is short, the system will spend a lot of time creating and destroying the thread. Java 5's thread pool overcomes these shortcomings. By executing multiple tasks on the reuse thread, the overhead of frequent thread creation and destruction is avoided, which greatly improves the server performance. Therefore, the network server model in this article will be as follows:

1. Create a listening port and a thread pool.

2. When a new connection is found, the thread pool is used to execute service tasks.

3. After the service is completed, release the thread to the thread pool.

The following describes how to use the APIS provided by the concurrent package of Java 5 to implement the server.

Initialization

Initialization includes creating thread pools and initializing listening ports. To create a thread pool, you can call java. util. concurrent. the static method newChahedThreadPool or newFixedThreadPool In the Executors class can also be created by creating a java. util. concurrent. threadPoolExecutor instance. Here we use the newFixedThreadPool method to create a thread pool.

ExecutorService pool = Executors. newFixedThreadPool (10 );

Indicates that a new thread pool is created, and 10 threads in the thread pool serve the task queue.

Use the ServerSocket object to initialize the listening port.

Private static final int PORT = 19527;
ServerListenSocket = new ServerSocket (PORT );
ServerListenSocket. setReuseAddress (true );
ServerListenSocket. setReuseAddress (true );

New Service connection

When a new connection is established and the accept returns, the service task is submitted to the thread pool for execution.

While (true ){
Socket socket = serverListenSocket. accept ();
Pool.exe cute (new ServiceThread (socket ));
}

Here, the thread pool object is used to execute the thread, reducing the overhead of every thread creation and destruction. After the task is executed, the thread is released to the thread pool.

Service Task

The service thread ServiceThread maintains a count to record the number of times the service thread is called. When a service task is called once, the count value increases by 1. Therefore, ServiceThread provides an increaseCount and getCount method to increase the count value by 1 and obtain the count value respectively. Because multiple threads may compete and access the count at the same time, the lock mechanism is required. Before Java 5, we can only use synchronized to lock it. Java 5 introduces ReentrantLock with finer granularity. We use ReentrantLock to ensure code thread security. The code below is as follows:

Private static ReentrantLock lock = new ReentrantLock ();
Private static int count = 0;
Private int getCount (){
Int ret = 0;
Try {
Lock. lock ();
Ret = count;
} Finally {
Lock. unlock ();
}
Return ret;
}
Private void increaseCount (){
Try {
Lock. lock ();
++ Count;
} Finally {
Lock. unlock ();
}
}

The service thread prints a welcome message to the client at the beginning,

IncreaseCount ();
Int curCount = getCount ();
HelloString = "hello, id =" + curCount + "\ r \ n ";
Dos = new DataOutputStream (connectedSocket. getOutputStream ());
Dos. write (helloString. getBytes ());

Then, use the submit method of ExecutorService to submit a Callable task and return a reference to the Future interface. This method is very effective for time-consuming tasks. After the submit task is executed, you can continue to execute the following code, and then you can use the get method of ure to obtain the result at an appropriate position, if the method has been executed at this time, you do not need to wait for the result to be obtained. If the method is still being executed, you need to wait until the execution is complete.

ExecutorService executor = Executors. newSingleThreadExecutor ();
Future future = executor. submit (new TimeConsumingTask ());
Dos. write ("let's do soemthing other". getBytes ());
String result = future. get ();
Dos. write (result. getBytes ());

TimeConsumingTask implements the Callable interface.

Class TimeConsumingTask implements Callable {
Public String call () throws Exception {
System. out. println ("It's a time-consuming task, you 'd better retrieve your result in the furture ");
Return "OK, here's the result: It takes me lots of time to produce this result ";
}
}

Here we use another new generic feature of Java 5. String is used as the type parameter when declaring TimeConsumingTask. The call function of the Callable interface must be implemented. Its function is similar to the run function in Runnable. The call function writes the code to be executed, the return value type is equivalent to the type value passed in the class declaration. In this program, we submitted a Callable task, and then the program will not be blocked, but continue to execute dos. write ("let's do soemthing other ". getBytes (); when the program runs to String result = future. when get () is run, if the call function has been executed, the return value is obtained. If the call function is still executed, wait until the execution is complete.
Related Article

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.