Use AJAX technology to implement mutex Technology in Web development (1)

Source: Internet
Author: User

I. Introduction

With AJAX technology, a browser page can send data requests to the server in the background while the front-end user interfaces remain active. This leads to a typical problem-the previous two activities simultaneously access common JavaScript and DOM data structures. Traditionally, the solution to this concurrent programming problem is not provided using JavaScript. This article describes an improved and proven mutex mechanism-it can implement concurrent programming using JavaScript to effectively overcome the limitations of JavaScript.

2. Why is there a mutex?

At any time, as long as there is a multi-threaded logic in the program that requires simultaneous access to the same data, there will be a problem of mutual exclusion. Under normal circumstances, these programs assume that the data they interact with will not change. The code used to access these shared data structures is called the "critical section", and each operation that allows only one operation is called a mutex operation. This situation also occurs in AJAX applications when the Code requirements from the XMLHttpRequest response are processed asynchronously and the data used in the user interface code is operated simultaneously. This type of shared data may be JavaScript variables that implement an MVC data model, or DOM of the web page itself. If either party makes improper modification to the shared data, the logic of both parties will be interrupted.

You may ask, "Why have I never encountered such a situation ?" Unfortunately, these types of problems are often time-dependent, also known as "Race Condition"). Therefore, they do not always occur, but are triggered by a certain probability based on multiple factors. To achieve robustness, rich Internet applications of RIA must take some measures to prevent this situation.

Therefore, we need to establish a mutex mechanism to ensure that there is only one critical section in each operation ). Most mainstream computer languages and execution frameworks provide several mutex mechanisms. However, unfortunately, these mutex mechanisms do not exist in the browser-side JavaScript language. Although there are already some excellent mutex algorithms that do not require special languages or environments to support, even these algorithms require functions not supported by JavaScript and browsers such as Internet Explorer. Finally, we had to adapt these algorithms to overcome these browser and language restrictions.

3. Bakery Algorithm

Among several famous computer science mutex algorithms, a famous algorithm is the Bakery algorithm invented by Lamport. This algorithm is applicable to controlling the shared storage competition among multiple threads when communication between two threads is shared storage. In this algorithm, the "bakery" image is compared to a semaphore. In order to buy bread, the customer must wait by serial number until their number is called. List 1 is the general framework of this algorithm from Wikipedia ). This algorithm enables every thread to enter and exit the critical section without conflict.

// Declare the global variable and assign the initial value to it
Enter, Number: array [1 .. N] of integer = {0 };
// The logic used by each thread...
// The "(a, B) <(c, d)" described below )"
// Meaning "( Thread (I ){
While (true ){
Enter [I] = 1;
Number [I] = 1 + max (Number [1],..., Number [N]);
Enter [I] = 0;
For (j = 1; j <= N; ++ j ){
While (Enter [j]! = 0 ){
// Wait until thread j receives its number
}
While (Number [j]! = 0)
& (Number [j], j) <(Number [I], I ))){
// Wait until the thread with a higher priority value equal to or less than this number appears. Then, the corresponding work can be executed.
}
}
// Critical section...
Number [I] = 0;
// Non-critical section...
}
}

List 1. Bakery algorithm pseudo code of Lamport

As shown above, this algorithm assumes that every thread knows its own thread number I) and the total number of active threads N ). It also assumes that there is a way to implement waiting or sleep); that is to say, there is a way to temporarily control the CPU to other threads. Unfortunately, JavaScript on Internet Explorer does not have any of these capabilities. However, if multiple parts of the code running on the same actual thread "Pretend" that each sub-part is running on an independent virtual thread, therefore, this Bakery algorithm will not be executed permanently. Moreover, JavaScript implements a mechanism to schedule a function after a specified delay. Therefore, we may skillfully modify the Bakery algorithm to meet the preceding conditions.

Iv. Wallace improvement of Bakery Algorithm

The main obstacle to implementing the Lamport Bakery algorithm using JavaScript is that there is no thread-level API-there is no way to know which thread is currently running or how many threads are active; there is no way to grant the CPU right to another waiting thread, and there is no way to create a new thread to manage other threads. For these reasons, we cannot even verify how to assign specific browser events, such as Button clicking and available XML responses, to the thread.

One way to overcome these obstacles is to use the Command design mode. Put a Command object together with all the data that needs to initialize the logic into all the logic that should be implemented in a critical section, we can "process" the Bakery algorithm into a class for managing commands. This mutex class is encapsulated as an independent command object method in the critical section only when other critical sections do not run. It seems that each critical section is in its own virtual thread. To this end, we use the setTimeout () Mechanism of JavaScript to control the CPU to another waiting command.
By defining a simple base class Command of these Command objects, see Command in List 2), we can define a new class, see Mutex in list 3) -Use it to implement the Wallace improvement algorithm of the Bakery algorithm. Note that although there are many methods in JavaScript to implement the class-based Object Concept (for the sake of conciseness, a simple method is used here, any object-oriented design can use the technology described here, as long as each Command object has a unique id and the entire critical section is encapsulated into a single method.

1 function Command (){
2 if (! Command. NextID) Command. NextID = 0;
3 this. id = ++ Command. NextID;
4 // non-synchronous API
5 this. doit = function () {alert ("DOIT called ");}
6 this. undo = function () {alert ("UNDO called ");}
7 this. redo = function () {this. doit ();}
8 // synchronous API
9 this. sDoIt = function () {new Mutex (this, "doit ");}
10 this. sUnDo = function () {new Mutex (this, "undo ");}
11 this. sReDo = function () {new Mutex (this, "redo ");}
12}

List 2. Command class for packaging Command objects

The above Command class implements the three critical section methods 5th ~ 7 rows); as long as a method call is encapsulated into a Mutex object, it is like 9th ~ 11 rows), you can use this method. It should be noted that the key difference between a normal method call, such as calling a non-synchronous method) and a synchronous method call: the irony is that we must assume that the synchronous method cannot run synchronously. In other words, when sDoIt () is called, we must assume that doit () is not running, even though sDoIt () has returned. The doit () method can be started only after a period of time. That is to say, you can regard a Mutex instance as starting a new thread.

1 function Mutex (cmdObject, methodName ){
2 // define static domains and Methods
3 if (! Mutex. Wait) Mutex. Wait = new Map ();
4 Mutex. SLICE = function (container ID, startID ){
5 Mutex. Wait. get (upload ID). attempt (Mutex. Wait. get (startID ));
6}
7 // define the instance method
8 this. attempt = function (start ){
9 for (var j = start; j = Mutex. Wait. next (j. c. id )){
10 if (j. enter
11 | (j. number & (j. number <this. number |
12 (j. number = this. number
13 & j. c. id <this. c. id ))))
14 return setTimeout
15 ("Mutex. SLICE (" + this. c. id + "," + j. c. id + ")", 10 );
16}
17 // run in mutex Access Mode
18 this. c [this. methodID] ();
19 // release mutex access
20 this. number = 0;
21 Mutex. Wait. remove (this. c. id );
22}
23 // constructor Logic
24 this. c = cmdObject;
25 this. methodID = methodName;
26 // here, both enter and number are false
27 Mutex. Wait. add (this. c. id, this );
28 this. enter = true;
29 this. number = (new Date (). getTime ();
30 this. enter = false;
31 this. attempt (Mutex. Wait. first ());
32}

List 3. Create a Mutex class to implement the Wallace Improved Algorithm


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.