Architecture Java concurrent model framework

zhaozj2021-02-16  45

China

DW China all content ............... DW China Technology Zone: Component Technology Java Technology Linux XML ............... DW China Special Topics: Safety Unicode Site Architecture ............... IBM full content search help IBM Home | Products & Services | Support & Download | Personalized Services

IBM: DeveloperWorks China website: Java: All articles

Build a Java concurrent model framework

content:

Basic Knowledge Simple Example Framework Overview Construction Frame Based on Framework Solution Conclusion Reference About Authors

Deng Hui (Dhui@263.net) Sun Ming (DHUI@263.net) Software Engineer

Java multi-threaded features provide great convenience to build high-performance applications, but also brings a lot of trouble. The problems between the thread synchronization, data consistency, etc. need to be careful, and there will be some subtle, difficult to debug errors. In addition, the application logic and thread logic are entangled together, which will cause the program's logical structure confusion, difficult to reuse and maintain. This article tries to give a solution to this problem, making it easy for developing multi-thread applications by building a concurrent model framework (Framework).

Basic knowledge Java language provides a good support for threads, implementation methods, and elegance. The implementation of the reintegration of the method, the implementation of the Semaphore and the Critical Section mechanism is very simple. It can easily implement synchronization operations between multi-threaded intervals to protect critical data. These features enable Java to become a leader in object-oriented language (C is trying to incorporate support parts of the BOOST library for threads). In Java, the support for object concurrency access is built. Each object has a monitor (Monitor), and only one thread is allowed to hold a monitor to perform access to the object, and those threads that have not got the monitor must wait until the Thread release monitor with a monitor. The object is declared through the synchronized keyword to obtain a monitor to access your own access. Synchronized declarations are only more effective for some relatively simple thread synchronization problems, and for which complex synchronization issues, Java provides additional solutions, WAIT / Notify / NotifyAll. The thread obtained by the object monitor can actively release the monitor by calling the object, waiting to wait on the object's thread waiting queue, at which time other threads can get a monitor to access the object, after which it can be called NOTIN / NotifyAll method To wake up the thread waiting for the WAIT method. In general, the call to the wait / notify / notifyAll method is based on certain conditions, such as the classic producer / consumer issue for the queue empty, full judgment. Readers who are familiar with POSIX will find that using Wait / Notify / NotifyAll can easily implement advanced synchronization technologies between one thread in POSIX: Condition variables. There are a lot of books, information about Synchronized, Wait / Notify / NotifyAll, in detail in the reference [3], and the Java memory model related to the thread and the thread is discounted, interested readers can Learn, don't you have described here. Simple example This article will be discussed around a simple example, which can be easier to highlight our ideas, methods, methods. This article wants to show the reader is these ideas, methods. These ideas are more suitable for concurrent problems in solving large-scale, complex applications. Consider a simple example, we have a service provider, which provides services outside an interface, the service content is very simple, is printed on the standard output to print Hello World. The class structure diagram is as follows: The code is as follows:

Interface service

{

Public void syhello ();

}

Class ServiceImp IMPLEMENTS Service

{

Public void syhello () {

System.out.println ("Hello World!");

}

}

Class Client

{

Public Client (Service S) {

_Service = S;

}

Public void requestService () {

_service.sayhello ();

}

Private service_service;

}

If there is a new demand now, the service must support the CLIENT's concurrent access. A simple way is to ensure the consistency of the internal data in front of each method in the Servicimp class (of course, it is not necessary for this example, because ServiceImp does not need to protected data. However, with the changes in demand, there may be it later). But this will have at least the following issues:

Now we have to maintain two versions of ServiceImp: Multi-threaded version and single-threaded version (some places, such as other projects, problems that may not be conclude), easy to bring synchronous updates and correctly select the version, bring trouble to maintenance. If multiple concurrent client frequently calls the service, because it is direct synchronous call, it will cause Client blocking to reduce service quality. It is difficult to make some flexible controls, such as: queuing according to the priority of Client, etc. These issues are particularly highlighted for large multi-threaded application servers, and for some simple applications (as examples herein) may not be considered at all. This article is to discuss the solutions of these problems, and simple examples in the text provide a platform for explaining problems, show ideas, and methods. How can I solve these problems better? Is there a solution that can be reused? Let us first put these questions, first talk about some problems related to the framework. Framework Overview Familiar with object-oriented readers must know that one of the biggest advantages of object-oriented is: software multiplexing. By multiplexing, you can reduce a lot of workloads and improve software development productivity. The multiplex itself is also a hierarchical, and the multiplexing of the code level and the reuse of the design architecture. Everyone may be familiar with some of the standard libraries in C language, which provides some common features to make your program. But these standard libraries do not affect your program structure and design ideas, just provide some functions to help your program completed work. They make you don't have to write generally universal features (such as Printf), which emphasizes the reuse of the program code itself, rather than the reuse of the design architecture. So what is the framework? The so-called frame, it is different from the general standard library, refers to a set of closely associated (class) classes, emphasizes each other's cooperation to complete some of the design concepts that can be used. These classes cooperate between these classes to be indispensable to each other. They have a considerable degree of impact your program's topography. The frame itself plans the backbone of the application, allowing the program to follow a certain process and motion, show a certain style and function. This makes the programmer do not have to pay for the versatile festival of versatility, focus on professional fields. One must emphasize that the framework is not existent, and it is also the most used. The framework is often aimed at a particular application area, on the basis of deep understanding of this application, abstract the application of the application, a model of these abstract concepts, is a tangible frame. Different specific applications are implemented on the abstraction concepts in the frame according to their own characteristics, thus imparting the functionality of the framework and completes the application. Based on the framework, there are two parts: frame parts and specific application parts. To achieve the goal of the framework multiplex, you must do isolation of the frame portion and the specific application portion. One power-oriented strong function: polymorphism, you can achieve this. Complete the interaction between abstraction in the framework, associate, and give specific implementations to specific applications. The Template Method design mode will generally use a large number of template method design patterns. Collection Framework in Java and Microsoft's MFC are well-frameful examples. Interested readers can study themselves. How to build a framework for the framework? Let us go back to the original problem, first analyze the reason. The reason for the two versions to maintain multithreading and single threads are due to mixing the application logic and concurrent logic, if it is possible to make good isolation and concurrent models, the application logic itself can be very good Reuse, and it is also easy to add concurrent logic to any impact on application logic.

The reason that causing Client blocking, performance reduction, and unable to perform additional control is that all service calls are synchronized, and the solution is simple, changed to asynchronous call mode, and separate the service calls and services. First introduce a concept, active object. The so-called active object is a passive object, the call and execution of the passive object method is in the same thread, the call of the passive object method is synchronized, blocking, general objects belong to Passive object; call and execution of the method of active objects are separated, active objects have their own independent executive thread, the call of the active object is initiated by other threads, but the method is performed in its own thread, active object The call to the method is asynchronous, non-blocking. The core of this framework is to use an active object to encapsulate concurrency logic, then forward the client's request to the actual service provider (application logic), so that both Client or the actual service provider do not have to care for concurrent, do not consider concurrency The data consistency problem brought. Thereby realizing isolation of application logic and concurrent logic, service calls, and services performed. The key implementation details are given below. This framework has the following components: an ActiveObject class, inheriting from thread, encapsulating an ActiveQueue class, primarily used to store the transferor request a MethodRequest interface, mainly used to encapper the caller's request, Command design mode One of its simple implementations of them are as follows:

// MethodRequest interface definition

Interface MethodRequest

{

Public void call ();

}

// ActiveQueue definition, actually a product / consumer queue

Class ActiveQueue

{

Public ActiveQueue () {

_Queue = new stack ();

}

Public synchronized void enqueue (MethodRequest MR) {

While (_Queue.size ()> queue_size) {

Try {

Wait ();

} catch (interruptedexception e) {

E.PrintStackTrace ();

}

}

_Queue.push (MR);

NotifyAll ();

System.out.println ("Leave Queue");

}

Public synchronized methodRequest dequeue () {

MethodRequest MR;

While (_Queue.empty ()) {

Try {

Wait ();

} catch (interruptedexception e) {

E.PrintStackTrace ();

}

}

MR = (MethodRequest) _Queue.POP ();

NotifyAll ();

Return MR;

}

Private stack _queue;

PRIVATE FINAL Static Int Queue_size = 20;

}

// ActiveObject definition

Class ActiveObject Extends Thread

{

Public ActiveObject () {

_Queue = new activityQueue ();

START ();

}

Public void enqueue (MethodRequest MR) {

_Queue.enqueue (MR);

}

Public void Run () {while (true) {

MethodRequest MR = _Queue.dequeue ();

Mr.call ();

}

}

PRIVATE ACTIVEQUE_QUEUE;

}

It can be seen from the above code that these classes have completed packages for concurrent logic. Developers only need to implement the MethodRequest interface as needed, and then define a service proxy class to provide the user, transform the service caller's request to the MethodRequest implementation in the service agent class, and give it to the active object. Using this frame, you can do the separation of application logic and concurrent models, so that developers concentrate on the application field, then combine with concurrent models, and can customize queuing mechanisms for ActiveQueue, such as priority, etc. . Framework-based solution This section will re-implement the previous examples using the framework described above to provide support for concurrency. The first step is completed first for the implementation of MethodRequest, and for our example, the implementation is as follows:

Class Sayhello IMPLEments MethodRequest

{

Public Sayhello (Service S) {

_Service = S;

}

Public void call () {

_service.sayhello ();

}

Private service_service;

}

This class completes the package for the service providing interface SayHello method. Next, a service proxy class is defined to complete the request package, queuing the function, of course, in order to transparency to the client, the class must implement the service interface. Defined as follows:

Class ServiceProxy IMPLEMENTS Service

{

Public serviceProxy () {

_Service = new serviceImp ();

_Active_Object = new activityObject ();

}

Public void syhello () {

MethodRequest MR = New Sayello (_SERVICE);

_Active_Object.enqueue (MR);

}

Private service_service;

Private activityObject_Active_object;

}

The other classes and interfaces are defined unchanged. The following comparison changes the changes in service calls before and after increasing the concurrent logic, and the caller logic increases, for the calling method of the Sayello service:

Service s = new serviceImp ();

Client C = New Client (s);

C.RequestService ();

After the concurrent logic is increased, the call method for the SayHello service:

Service s = new serviceProxy ();

Client C = New Client (s);

C.RequestService ();

It can be seen that there is no change in Client's serviceIMP before and after increasing the increasing logic, and the use method is also very consistent. ServiceIMP can also be reused independently. The class structure diagram is as follows:

Readers are easy to see that the use of frames also adds some complexity, and for some simple applications, it may not be necessary to use this framework at all. I hope the reader can determine according to its own actual situation. Conclusion This article discusses how to archive a Java concurrent model framework in this paper, which uses some common technologies for building frameworks. Of course, the framework and some mature commercial frames are very tender, such as no consideration call. There is a return value, but its ideological method is consistent, I hope the reader can understand, so it is very helpful to build your own framework or understanding some other frameworks. The reader can expand the framework in this article, directly applied to their own work. References [1] For many detail issues in the framework of concurrency models, interested readers can study themselves. The advantages and disadvantages of this framework are listed below: Advantages: Enhanced the application's concurrency, simplifying the requests and services of the complex service of synchronous control, making the service request to queue, flexible control application logic and concurrent model Separate, make the program structure clear, easy to maintain, reuse can enable developers to concentrate on the disadvantage of the application field:

Due to the presence of the presence required by the frame, the complexity of the program is added to some extent. If the application needs too much activity object, the thread switching will cause performance decline in performance, it may cause debugging difficult reference [1] Active Object An Object Behaviooral Pattern for Concurrent, Schmidt, Douglass, Lavender, R. Greg, Programming, http: //www.cs.wustl.edu/~schmidt/PDF/Act-Obj.pdf [2] Effective Java Programming Language Guide, Joshua Bloch [ 3] Double-Checked Locking: Clever, But Broken, Brian Goetz, http://www.javaworld.com/javaworld/jw-02-2001/jw-0209-double.htm [4] Design Patterns, Gamma, ET. Al., AddIn Wesley

转载请注明原文地址:https://www.9cbs.com/read-25794.html

New Post(0)