Java advanced-parsing the multithreading mechanism in Java

Source: Internet
Author: User
Java advanced-parse the multi-thread mechanism in Java-general Linux technology-Linux programming and kernel information. The following is a detailed description. Differences between processes and applications



A Process is a concept initially defined to indicate the basic execution unit of an application in a memory environment in a multi-user, multi-task operating system environment such as Unix. Taking a Unix operating system as an example, a process is a basic component in a Unix operating system environment and a basic unit for system resource allocation. Almost all user management and resource allocation tasks completed in Unix are implemented through the control of application processes by the operating system.

The source programs written in C, C ++, Java, and other languages are compiled into executable files by the corresponding compiler and submitted to the computer processor for running. An application in an executable state is called a process. From the user's perspective, a process is an execution process of an application. From the core perspective of the operating system, processes represent the basic units of the memory allocated by the operating system, CPU time slice, and other resources, and are the runtime environment provided for running programs. The difference between a process and an application is that an application is stored as a static file in a hard disk or other storage space of a computer system, A process is a system resource management entity maintained by the operating system under dynamic conditions. The main features of application processes in a multitasking environment include:

● The process has an initial entry point for memory units during execution, and it always has an independent memory address space during process survival;

● The lifetime status of a process includes creation, readiness, running, blocking, and death;

● The Process status can be divided into user and core states based on the running commands sent to the CPU during the execution of the application process. In the user State, processes execute application commands, and in the core State, application processes execute operating system commands.

During Unix startup, the system automatically creates swapper, init, and other system processes to manage memory resources and schedule user processes. In a Unix environment, no matter the process created by the operating system or executed by the application, it has a unique process identifier (PID ).

Differences between processes and Java threads

The application has an initial entry point address of the memory space during execution, a code execution sequence during execution, and a memory exit point address used to identify the end of the process, each time point in the process execution process has a unique processor command corresponding to the memory unit address.

The Thread defined in Java also includes a memory entry point address, an exit point address, and a code sequence that can be executed sequentially. However, the main difference between a process and a thread is that the thread cannot be executed independently and must run in an active application process, therefore, it can be defined that the thread is a concurrent sequential code stream within the program.

The Unix and Microsoft Windows operating systems support multi-user and multi-process concurrent execution, while the Java language supports concurrent execution of multiple execution threads within the application process. Multithreading means that multiple logical units of an application can be executed concurrently. However, multithreading does not mean that multiple user processes are being executed, and the operating system does not allocate independent system resources to each thread as an independent process. A process can create its child processes. The child process and the parent process have different executable code and data memory space. In the process used to represent the application, multiple threads share the data memory space, but each thread must have an independent execution stack and Context ).

Based on the preceding differences, a thread can also be called a Light Weight Process (LWP ). Different threads allow task collaboration and data exchange, making computer system resource consumption very cheap.

Threads must be supported by the operating system. Not all types of computers support multi-threaded applications. The Java programming language combines thread support with the language runtime environment to provide multi-task concurrent execution capabilities. This is like a person in the Process of housework, put the clothes in the washing machine, automatically wash, put the rice in the rice cooker, and then start cooking. When the food is ready, the food is cooked and the clothes are washed.

Note that using multithreading in applications does not increase the CPU data processing capability. Only when Java programs are divided into multiple concurrent execution threads on a multi-CPU computer or under the network computing architecture, multiple threads can be started to run simultaneously, only by running different threads in Java virtual machines based on different processors can the execution efficiency of applications be improved.

In addition, multi-threaded applications are advantageous if the application must wait for resources with slow data throughput, such as network connections or database connections. Internet-based applications must be multi-threaded. For example, when developing server-side applications that support a large number of clients, you can create an application to respond to client connection requests in the form of multiple threads, so that each connection user excludes one client connection thread. In this way, the user feels that the server only serves to connect to the user, thus shortening the server's client response time.

Multi-thread programming in Java



Using Java to implement multi-threaded applications is simple. Two methods can be used to inherit from or implement different multi-threaded applications: one is that the concurrent running objects of applications directly inherit the Java Thread class; another way is to define concurrent execution objects to implement the Runnable interface.

Multi-Thread Programming Method inherited from Thread class

A Thread class is a class defined in JDK for controlling Thread objects. It encapsulates methods used for Thread control. See the following sample code:

// Consumer. java

Import java. util .*;

Class Consumer extends Thread

{

Int nTime;

String strConsumer;

Public Consumer (int nTime, String strConsumer)

{This. nTime = nTime;

This. strConsumer = strConsumer;

}

Public void run ()

{

While (true)

{Try

{

System. out. println ("Consumer name:" + strConsumer + "");

Thread. sleep (nTime );

}

Catch (Exception e)

{

E. printStackTrace ();

}}}

Static public void main (String args [])

{Consumer aConsumer = new Consumer (1000, "aConsumer ");

AConsumer. start ();

Consumer bConsumer = new Consumer (2000, "bConsumer ");

BConsumer. start ();

Consumer cConsumer = new Consumer (3000, "cConsumer ");

CConsumer. start ();

}}

From the code above, we can see that the multi-Thread execution underground Consumer inherits the Thread class Thread in Java and creates three instances of Consumer objects in the main method. When the start method of the object instance is called, The run method defined in the Consumer class is automatically called to start the object thread to run. The result of thread running is to print the content of strConsumer, a string member variable in the object instance at every nTime interval.

It can be concluded that the multi-Thread programming method inheriting the Thread class is to make the application class inherit the Thread class and implement the concurrent processing in the run method of the class.



Multi-thread programming method for implementing the Runnable interface



Another method provided in Java to implement multi-threaded applications is to implement the Runnable interface for multi-threaded objects and define the run method used to start the thread in this class. The advantage of this definition method is that multi-threaded application objects can inherit other objects, rather than the Thread class, so as to increase the logic of the class definition.

The code of the multi-threaded application framework implementing the Runnable interface is as follows:

// Consumer. java

Import java. util .*;

Class Consumer implements Runnable

{

... ...

Public Consumer (int nTime, String strConsumer ){... ...}

Public void run (){... ...}

Static public void main (String args [])

{

Thread aConsumer = new Thread (new Consumer (1000, "aConsumer "));

AConsumer. start ();

// The Running thread of other object instances

//... ...

}}

The code above shows that this class implements the Runnable interface and defines the run method in this class. The implementation method of this multi-threaded application is different from that of a multi-threaded application that inherits the Thread class. In the above code, you can create a Thread object instance and use the application object as a parameter for creating a Thread class instance.

Synchronization between threads

Multiple Threads of a Java application share the data resources of the same process. Multiple User threads may simultaneously access sensitive content during concurrent running. Java defines the concept of thread synchronization to maintain the consistency of shared resources. The following describes the implementation of multi-thread synchronization in Java based on the synchronization control method between threads in the mobile communication billing system recently developed by the author.

The code of the Customer Account class definition framework without the multi-thread synchronization control policy is as follows:

Public class RegisterAccount

{Float fBalance;

// Customer's Payment Method

Public void deposit (float fFees) {fBalance + = fFees ;}

// Call billing method

Public void withdraw (float fFees) {fBalance-= fFees ;}

... ...

}

Readers may think that the above Code can fully meet the actual needs of the billing system. Indeed, the program is indeed reliable in a single-threaded environment. However, what is the situation of concurrent running of multiple processes? Assume that the customer pays the fee in the customer service center and uses the mobile communication device to start the billing process, at the same time, the service center staff also submitted the payment process for operation. The reader can see that, in this case, the handling of customer accounts is not serious.

How can this problem be solved? It is easy to add the keyword synchronized used to identify the synchronization method in the RegisterAccount class method definition. In this way, the shared resources involved in the method (the fBalance member variable in the above Code) will be added with a shared lock during the execution of the synchronous method, to ensure that only the method can access Shared resources during the running of the method, until the thread of the method stops running and opens the shared lock, other threads can access these shared resources. When the shared lock is not opened, other threads accessing shared resources are blocked.

The following code defines the RegisterAccount class after the thread synchronization policy is controlled:

Public class RegisterAccount

{Float fBalance;

Public synchronized void deposit (float fFees) {fBalance + = fFees ;}

Public synchronized void withdraw (float fFees) {fBalance-= fFees ;}

... ...

}

From the code format defined by the thread synchronization mechanism, we can see that the synchronization definition keyword synchronized is appended to the method access attribute keyword (public) for shared resources, this allows the synchronization method to assign shared locks to these sensitive resources when accessing shared resources to control the resource exclusiveness during the execution of the method, achieving consistent management and maintenance of data resources in the application system.

Thread Status Control



Here, we need to make it clear that no matter whether the Thread class is inherited or the Runnable interface is used to implement the multi-Thread capability of the application, we need to define the run method used to complete the actual function in this class, this run method is called the Thread Body ). Depending on the state of the thread body in the computer system memory, threads can be divided into creation, ready, running, sleep, suspended, and dead types. The characteristics of these threads under the thread state type are:

Creation status: when the new keyword is used to create a thread object instance, it only exists as an object instance, and the JVM does not allocate resources such as CPU time slice to it;

Ready state: Call the start method in the created thread to convert the state of the thread to ready state. At this time, the thread has obtained other system resources except the CPU time, and only waits for the JVM thread scheduler to schedule the thread according to the thread priority, this gives the thread the opportunity to obtain the CPU time slice.

Sleep Status: During thread running, you can call the sleep method and specify the thread's sleep time in the method parameters to convert the thread state to sleep state. At this time, the thread stops running the specified sleep time without releasing the resources occupied. After the time arrives, the thread is rescheduled and managed by the JVM thread scheduler.

Pending status: You can call the suspend method to convert the thread status to pending. At this time, the thread will release all the resources occupied, and the JVM will schedule the transfer to the temporary storage space until the application calls the resume method to resume the thread running.

Dead state: When the thread body stops running or the stop method of the thread object is called, the thread stops running and the JVM reclaims the resources occupied by the thread.

The corresponding methods are defined in the Java Thread class for controlling and managing the thread status in the application.

Thread Scheduling

The significance of thread calling is that the JVM should coordinate system-level for multiple running threads to avoid application system crashes or crashes because multiple threads compete for limited resources.

Java defines the priority policy for threads to distinguish the operating system from the user. Java divides the thread priority into 10 levels, which are represented by numbers ranging from 1 to 10. The larger the number, the higher the Thread level. Correspondingly, the member variables MIN_PRIORITY, MAX_PRIORITY, and NORMAL_PRIORITY, which indicate the lowest, highest, and general priorities of the Thread class, are defined as 1, 10, and 5 respectively. When a thread object is created, the default thread priority is 5.

To control the thread running policy, Java defines a thread scheduler to monitor all the threads in the ready state in the system. The thread scheduler determines the thread to be put into the processor to run according to the thread priority. When multiple threads are in the ready state, high-priority threads will be executed before low-priority threads. The thread scheduler also uses the "preemptible" policy to schedule thread execution. That is, if a thread with a higher priority enters the ready state during the current thread execution process, the thread with a higher priority is immediately scheduled for execution. All threads with the same priority are rotated to allocate CPU time slices.

The method for setting the thread priority in an application is very simple. After creating a thread object, you can call the setPriority method of the thread object to change the running priority of the thread, you can also call the getPriority method to obtain the priority of the current thread.

A special thread in Java is a low-level thread called Daemon. This thread has the lowest priority and is used to provide services for other objects and threads in the system. To set a user thread as a daemon, call the setDaemon method of the thread object before the thread object is created. A typical example of a daemon thread is the automatic collection of system resources in the JVM. It is always running in a low-level state for real-time monitoring and management of recoverable resources in the system.

Thread Group Management

Java defines a ThreadGroup object in a multi-threaded running system, which is used to implement centralized management of threads by group according to specific functions. Each thread created by the user belongs to a thread group. This thread group can be specified when the thread is created, or the thread group can be left unspecified to keep the thread in the default thread group. However, once a thread is added to a thread group, the thread will remain in the thread group until the thread dies, and the thread group to which the thread belongs cannot be changed midway through.

When the Java Application program runs, JVM creates a thread group named main. Unless specified separately, all threads created in the application belong to the main thread group. In the main thread group, you can create a thread group with other names and add other threads to the thread group. This type of push constitutes a tree management and inheritance relationship between the thread and the thread group.

Similar to a thread, you can schedule, manage the status, and set the priority of a thread group object. All threads added to a thread group are treated as uniform objects during thread group management.

Summary

This article analyzes and explains the nature of threads in the Java platform and the multithreading policies of applications. Unlike other operating system environments, Java runtime environments have threads that are similar to processes in multi-user and multi-task operating systems. However, in terms of running and creating processes and threads, processes are significantly different from Java threads.

In a Unix operating system, an application can use the fork function to create sub-processes. However, the sub-process and the application process have independent address spaces, system resources, and code execution units, in addition, process scheduling is completed by the operating system, which makes communication and thread coordination between application processes more complex. Multithreading in Java applications is multiple parallel code execution bodies that share resources of the same application system. The communication and coordination methods between threads are relatively simple.

It can be said that Java's support for multi-threaded applications enhances Java's advantages as a network programming language, it lays a solid foundation for implementing concurrent access to multiple clients in the distributed application system and improving server response efficiency.

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.