Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What is the handling of Java blocking

2025-01-27 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

This article mainly introduces the relevant knowledge of how to deal with Java blocking, the content is detailed and easy to understand, the operation is simple and fast, and has a certain reference value. I believe you will gain something after reading this article on how to handle Java blocking. Let's take a look at it.

Before Java1.4, Java network programming is only blocking mode, in Java1.4 and after, Java provides non-blocking network programming API. From the perspective of the development of Java, due to the rapid development of Java and the improvement of JVM performance, there are more and more server-side application development, and more and more high-performance network applications are required. This is the main reason for Java to launch non-blocking network programming.

In the blocking network programming mode, for each individual network connection, there must be a thread to bind the network connection to deal with the network byte flow. Here is a piece of code:

Public static void main (String [] args) {try {ServerSocket ssc = new ServerSocket (23456); while (true) {System.out.println ("Enter Accept:"); Socket s = ssc.accept (); try {(new Thread (new Worker (s)). Start ();} catch (Exception e) {/ / TODO e.printStackTrace ();} catch (IOException e) {e.printStackTrace () }} public static class Worker implements Runnable {private Socket s; private boolean running = true;; public Worker (Socket s) {this.s = s;} public void run () {try {InputStream is = s.getInputStream (); OutputStream os = s.getOutputStream (); while (running) {byte [] b = this.readByLength (is, 1024); this.process (b);} catch (Throwable t) {/ / TODO t.printStackTrace () } private byte [] readByLength (InputStream is, int contLen) throws IOException {byte [] b = new byte [contLen]; int off = 0; int length = 0; while ((length = is.read (b, off, contLen-off)) > = 0) {off = + length; if (off > = contLen) {break;} return b;} private void process (byte [] b) {}}

In this code, we see two blocking methods, the accept () method of ServerSocket, and the read () method of InputStream. So we need two types of threads to process separately. And the life cycle of the thread bound by each blocking method is consistent with the life cycle of the network connection. Based on the above reasons, NIO arises at the historic moment. On the one hand, it establishes a thread correspondence for each network connection, and at the same time, each thread has a large number of threads in an idle state other than reading and writing, so hoping to reduce the number of threads, reduce each idle state, and improve the execution efficiency of a single thread is actually making more full use of the computing and running capabilities of CPU (because if there are a large number of links. There are a large number of threads, and a large number of threads are blocked in the read () or write () method. At the same time, CPU needs to schedule and switch between these threads frequently, which will inevitably lead to a large number of system calls and resource competition. On the other hand, we hope to improve the performance of network IO and hard disk IO operation. There are three main new features in NIO:

1. Data buffering processing (ByteBuffer): because the primitive type of data communication between operating system and application is byte, which is also the basic unit of IO data operation, in NIO, every basic native type (except boolean) has the implementation of Buffer: CharBuffer, IntBuffer, DoubleBuffer, ShortBuffer, LongBuffer, FloatBuffer and ByteBuffer. Data buffering enables continuous processing of data streams in IO operations. At present, there are two kinds of ByteBuffer, one is Direct ByteBuffer, the other is that NonDirect ByteBuffer;ByteBuffer is an ordinary Java object, which follows the rules of the existence of objects in the Java heap, while Direct ByteBuffer is the native code, whose memory allocation is not in the Java stack and is not affected by Java memory recovery. Each Direct ByteBuffer is a continuous memory space allocated directly, which is also one of the important ways for NIO to improve performance. In addition, a very important feature of data buffering is that one or more logical view buffers (View Buffer) can be established based on one data cache. For example, with View Buffer, a Buffer of type Byte can be replaced with a buffer of type Int, or a large buffer can be converted into many small Buffer. It is called View Buffer because this transformation is only logical and does not physically create a new Buffer. This brings us a lot of convenience to operate Buffer.

two。 Asynchronous Channel (Channel): Channel is an object with a lot of native code closely integrated with the operating system. The non-blocking operation of network programming is realized through Channel, and it is also effectively combined with ByteBuffer and Socket to make full use of the characteristics of non-blocking and ByteBuffer. We will see the specific usage of SocketChannel later.

3. Conditional selection (Readiness Selection): most operating systems have API that supports conditional selection of ready IO channels, which ensures that a thread can effectively manage multiple IO channels at the same time. In NIO, by Selector (maintaining the status of registered Channel and these Channel), SelectableChannel (Channel that can be managed by Selector), and SelectionKey (SelectionKey identifies the mapping between Selector and SelectableChannel, once a Channel is registered in Selector, a SelectionKey object is returned. SelectionKey saves two types of states: which operations are registered by the corresponding Channel; those operations of the corresponding Channel are ready to perform corresponding data operations) to achieve this function.

The package of NIO mainly contains several abstract data types:

◆ Buffer: a linear table structure that contains data and is used for reading and writing. It also provides a special class for memory-mapped files' Iswap O operations.

◆ Charset: it provides operations for mapping Unicode strings to byte sequences and inverse mapping.

◆ Channels: includes socket,file and pipe pipes, all of which are full-duplex channels.

◆ Selector: multiple asynchronous Istroke O operations are concentrated in one or more threads (which can be thought of as the object-oriented version of the select () function in Unix).

A typical programming model for NIO non-blocking is as follows:

Private Selector selector = null; private static final int BUF_LENGTH = 1024; public void start () throws IOException {if (selector! = null) {selector = Selector.open ();} ServerSocketChannel ssc = ServerSocketChannel.open (); ServerSocket serverSocket = ssc.socket (); serverSocket.bind (new InetSocketAddress (80)); ssc.configureBlocking (false); ssc.register (selector, SelectionKey.OP_ACCEPT); try {while (true) {int nKeys = UnblockServer.this.selector.select () If (nKeys > 0) {Iterator it = selector.selectedKeys (). Iterator (); while (it.hasNext ()) {SelectionKey key = (SelectionKey) it.next (); if (key.isAcceptable ()) {ServerSocketChannel server = (ServerSocketChannel) key.channel (); SocketChannel channel = server.accept (); if (channel = null) {continue;} channel.configureBlocking (false); channel.register (selector, SelectionKey.OP_READ) } if (key.isReadable ()) {readDataFromSocket (key);} it.remove ();} catch (IOException ioe) {ioe.printStackTrace ();}} / * @ param key * @ throws IOException * / private void readDataFromSocket (SelectionKey key) throws IOException {ByteBuffer buf = ByteBuffer.allocate (BUF_LENGTH); SocketChannel sc = (SocketChannel) key.channel (); int readBytes = 0; int ret Try {while ((ret = sc.read (buf.buf () > 0) {readBytes + = ret;}} finally {buf.flip ();} / process buffer / / buf.clear ();}

From this program, we can basically understand some characteristics of NIO network programming. The way of creating a SocketServer has changed. We need to specify a non-blocking mode, and we need to create a Channel and register in Selector. Similarly, the process of establishing a network connection is the same mode, and then there is a conditional choice (Readiness Selection). In this way, each of our threads only needs to deal with one type of network selection. In terms of code, we find that the way it is handled is completely different from that of blocking, and we need to completely rethink how to write a module for network communication:

1. Persistent connection timeout (Timeout), because API does not directly support the parameter setting function of timeout, so we need to implement such a function ourselves.

two。 How to use Selector, because the processing capacity of each Selector is limited, so in a large number of links and message processing, we need to consider how to use multiple Selector.

3. In the non-blocking case, read and write are no longer blocking, so you need to consider how to read the determined message completely; how to ensure that the data is written into the IO when the network environment is not very good.

4. How to apply ByteBuffer, creating a large number of ByteBuffer itself is very resource-consuming; how to use ByteBuffer effectively? At the same time, the operation of ByteBuffer needs to be carefully considered, because there are position (), mark (), limit (), capacity, and so on.

5. Because each thread is faced with a series of network connections when dealing with network connections, we need to consider how to better use and schedule multithreads. In the processing of messages, it is also necessary to ensure a certain order. For example, login messages arrive. Only after login messages are processed can other types of messages on the same link be processed.

6. Memory leaks that may occur in network programming.

On NIO's access processing framework, there are about two types of concurrent threads:

1.Selector threads, each Selector occupies a separate thread, because the processing capacity of each Selector is limited, it requires multiple Selector to work in parallel.

two。 For each link in the Ready state, the thread needs to process the corresponding message; for this type of message, the concurrent thread needs to work together to process. In this process, the integrity of the message may be required constantly; it also involves that the messages on each link may have timing, so the corresponding timing may also be required in processing.

The current open source NIO framework implementations in the community include MINA, Grizzly, NIO framework, QuickServer, xSocket, etc., of which MINA and Grizzly are the most active, and the code quality is also very high. The two of them are also quite different in the way they achieve it. (most of Java's open source servers have rewritten the network portion with NIO. )

This is the end of the article on "how to deal with Java blocking". Thank you for reading! I believe you all have a certain understanding of "how to handle Java congestion". If you want to learn more, you are welcome to follow the industry information channel.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 257

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report