Java thread Defects

Source: Internet
Author: User

Allen Holub pointed out that the thread model of the Java programming language may be the weakest part of the language. It is not suitable for actual complex program requirements, and it is not object-oriented at all. We recommend that you modify and supplement the Java language to solve these problems.

The Java thread model is one of the most difficult and satisfying parts of the language. Although the Java language itself supports thread programming, it only applies to very small application environments with little support for thread syntax and class packages.

Most books on Java thread programming have repeatedly pointed out the defects of the Java thread model and provided a class library to solve these problems. I call these classes as first aid kits because the issues they can solve should be included in the Java language's own syntax. In the long run, the syntax rather than the class library method can produce more efficient code. This is because the compiler and Java Virtual Machine (JVM) can optimize program code together, and these optimizations are difficult or impossible to implement for the code in the class library.

In my book "Taming Java Threads" (see references) and in this article, I further suggest modifying the Java programming language itself, so that it can truly solve these thread programming problems. The main difference between this article and my book is that I have made more thoughts when writing this article, so I have improved the proposals in this book. These suggestions are just tentative-my personal thoughts on these issues, and implementation of these ideas requires a lot of work and comments from colleagues. But this is, after all, the beginning. I have a dedicated working group for solving these problems. If you are interested, please send e-mail to the threading@holub.com. Once I start, I will send you a notification.

The suggestions made here are very bold. Some people suggest minor and minor modifications to the Java language specification (JLS) (see references) to solve the current fuzzy JVM behavior, but I want to improve it more thoroughly.

In actual drafts, many of my suggestions include introducing new keywords for this language. Although it is usually required not to break through the existing code of a language is correct, if the language does not need to remain unchanged so outdated, it must be able to introduce new keywords. To avoid conflict between the introduced keyword and the existing identifier, I will use a ($) character, which is invalid in the existing identifier. (For example, use $ task instead of task ). In this case, the command line switch of the compiler must be supported to use variants of these keywords instead of ignoring the dollar sign.

Concept of task

The fundamental problem with the Java thread model is that it is not object-oriented at all. Object-oriented (OO) designers do not consider the issue from the thread perspective at all; they consider synchronous asynchronous information (synchronous information is processed immediately-the message handle is returned only after the information processing is complete; after receiving asynchronous information, it will be processed in the background for a period of time-and the message handle will be returned before the information processing is completed ). The Toolkit. getImage () method in Java programming language is a good example of asynchronous information. The message handle of getImage () is immediately returned without waiting for the entire image to be retrieved by the background thread.

This is an object-oriented (OO) processing method. However, as mentioned above, the Java thread model is not object-oriented. A Java programming language thread is actually a run () process, which calls other processes. There is no object, asynchronous or synchronous information, or other concepts here.

One solution I have discussed in depth in my book is to use an Active_object. An active object is an object that can receive asynchronous requests. It can be processed after receiving the request for a period of time. In Java programming language, a request can be encapsulated in an object. For example, you can transmit an instance implemented through the Runnable interface to this active object. The run () method of this interface encapsulates the work to be done. This runnable object is discharged into the queue by this active object. When it is its turn to execute it, the active object uses a background thread to execute it.

The asynchronous information running on an active object is actually synchronized, because they are retrieved and executed by a single service thread in order from the queue. Therefore, using an active object in a more procedural model can eliminate most synchronization problems.

In a sense, the entire Swing/AWT subsystem of the Java programming language is an active object. The only safe way to send a message to a Swing queue is to call a message similar to SwingUtilities. invokeLater () method, so that a runnable object is sent in the Swing event queue. When it is its turn to execute, the Swing event processing thread will process it.

So my first suggestion is to add the concept of a task to the Java programming language to integrate the active object into the language. (The concept of task is based on Intel's RMX operating system and Ada programming language. Most Real-time Operating Systems Support similar concepts .)

A task has a built-in active object distribution program that automatically manages all the mechanisms that process asynchronous information.

Defining a task is basically the same as defining a class. However, you only need to add an asynchronous modifier before the task method to instruct the allocating program of the active object to process these methods in the background. Refer to the class-based method in Chapter 9 of my book and look at the following file_io class. It uses the Active_object class discussed in "Taming Java Threads" to Implement Asynchronous write operations:

All write requests are queued in the active-object Input Queue using a dispatch () process call. Any exception occurred when processing the asynchronous information in the background is handled by the Exception_handler object, which is transferred to the File_io_task constructor. When you want to write content to a file, the Code is as follows:

The main problem with this class-based processing method is that it is too complicated-for such a simple operation, the code is too complicated. After the $ task and $ asynchronous keywords are introduced to the Java language, you can rewrite the previous Code as follows:

Note that the asynchronous method does not specify the return value because its handle is returned immediately, instead of waiting for the request to be processed. Therefore, there is no reasonable return value. For the derived model, the $ task keyword is the same as the class Keyword: $ task can implement interfaces, inherit classes, and inherit other tasks. The method marked with the asynchronous keyword is processed by $ task in the background. Other methods will run synchronously, just like in the class.

The $ task keyword can be modified with an optional $ error clause (as shown above), which indicates that there will be a default handler for any exceptions that cannot be caught by the asynchronous method itself. I use $ to represent the thrown exception object. If the $ error clause is not specified, a reasonable error message (probably stack trace information) is printed ).

Note: To ensure thread security, the parameters of the asynchronous method must be immutable. The runtime system should use relevant semantics to ensure this immutability (simple replication is usually not enough ).

All task objects must support some pseudo-messages, such:

In addition to common modifiers (such as public), the task keyword should also accept a $ pooled (n) modifier, which causes the task to use a thread pool, instead of using a single thread to run asynchronous requests. N specifies the size of the required thread pool. If necessary, this thread pool can be increased, but it should be reduced to the original size when the thread pool is no longer needed. Pseudo-field $ pool_size returns the original n parameter value specified in $ pooled (n.

In chapter 8 of "Taming Java Threads", I provided a socket handler on the server side as an example of a thread pool. It is a good example of a job that uses a thread pool. The basic idea is to generate an independent object. Its job is to monitor a server socket. Every time a client connects to the server, the server object will capture a pre-created sleep thread from the pool and set this thread to serve the client connection. The socket server will generate an additional customer service thread, but when the connection is closed, these additional threads will be deleted. The recommended syntax for implementing the socket server is as follows:

The Socket_server object uses an independent background thread to process asynchronous listen () requests. It encapsulates the "accept" loop of the socket. When each client connects, listen () requests a Client_handler to process the request by calling handle. Each handle () request is executed in their own thread (because this is a $ pooled task ).

Note that each asynchronous message sent to $ pooled $ task actually uses its own thread for processing. In typical cases, a $ pooled $ task is used for autonomous operations. To solve potential synchronization problems related to access status variables, the best solution is to use this in the $ asynchronous Method as a unique copy of the object to which it points. This means that when an asynchronous request is sent to a $ pooled $ task, a clone () operation is executed and the this pointer of this method points to this cloned object. Inter-thread communication can be achieved through synchronous access to the static area.

Improved synchronized

In most cases, $ task eliminates the synchronization operation requirements, but not all multithreading systems use tasks. Therefore, we also need to improve the existing thread module. The synchronized keyword has the following Disadvantages: a timeout value cannot be specified. A thread waiting for request lock cannot be interrupted. You cannot safely request multiple locks. (Multiple locks can only be obtained in order .)

To solve these problems, extend synchronized syntax.

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.