Multi-threaded (foundation)

xiaoxiao2021-03-30  197

[Writing in front] With the development of computer technology, the programming model is increasingly complex. But multi-threaded programming model is the final model of computer system architecture. With the continuous rise of CPU, the hardware of X86 architecture has Become a bottle, in this architecture CPU frequency up to 4G. In fact, 3.6G clocked CPU has been close to the peak. If it is not fundamentally updated the current CPU architecture (it is not possible for a long time Then, the method of continuing the CPU performance is the ultra-thread CPU mode. Then, the job system, the application wants to play the maximum performance of the CPU, which is to change to a parallel processing system and concurrent application based on multi-threaded programming models. Therefore, master multithreading programming model is not only the means of improving application performance, but also the core idea of ​​next-generation programming model. The purpose of multi-threaded programming is "Maximize the use of CPU resources", when a certain thread is not processed When you need to occupy a CPU and only resources such as I / O, OEMBIOS, so that other threads that need to occupy the CPU resource have access to CPU resources. So fundamentally, this is the ultimate goal of multi-threaded programming. [First need to clarify Problem] As the difference between the procedures and processes, you have to master multithreading programming. The problem that the first to figure out is: the difference between thread objects and threads. Thread objects are objects that can generate threads. For example, in the Java platform Thread object, Runnable Object. Thread refers to a pointing sequence that is being executed. On the Java platform, it refers to the start () from a thread object. The relatively independent process of the section running the RUN method. Given the author's level, it cannot be used More exact words to describe their definitions. But these two concepts of essential differences, please experience the initiator, as the introduction of in-depth and routine analysis, will slowly understand the true meaning of their representatives. The world is difficult to start, and the world is threatened. Let us first start with the simplest "single thread". (1) Tape Number Description is just a relatively speaking single thread. (2) Based on Java Class Beginclass { Public static void main (string [] args) {for (INT i = 0; i <100; i ) system.out.println ("Hello, World!");}} If we successfully compile the java file, then Typing on the command line: What happened to Java BeginClass? Every Java programmer starts learning Java's first from him. In minutes, you know what happened? The JVM process is started, in the same JVM process, there is only one process, it is itself. Then in this JVM environment, all programs Running is running in thread. JVM will first generate a main thread, which is running the entry point of the specified program. In this program, the main thread starts running from the main method. When the main method is over, the main thread is shipped after the MAIN method Complete. The JVM process also exits. We see a main thread running the main method, so that only one thread execute program logic is called single thread. This is the single-threaded environment provided by JVM, In fact, the underlying of the JVM has at least garbage recycling such a background thread and other non-Java threads, but these threads we are not accessible, we only think it is a single thread. The main thread is started by JVM, here it Not from thread objects. In this thread, it runs this instruction sequence. Understand it, but it does not have more you can study. [Contact Multi-thread] Class mythread extends thread {public void Run () { System.out.println ("Thread Say: Hello, World!");}} Public class mostthreads {public static void main (string [] args) {new mythread (); new mythread (). Start (); system. Out.println ("

Main Say: Hello, World ");}} Execute this program, the first line of the main method produces a thread object, but there is no thread start. The second line of the main method produces a thread object and launched a thread. Main Method Third line, after generating and starting a thread, the main thread also continues to perform other statements. We don't study the specific content of the Thread object, and then recall the two concepts, thread objects and threads. In Java, Thread objects are a normal Object subclass generated by JVM. Thread is a running process assigned to this object. We said what thread is doing, nothing to say, but what is the running process. If you don't understand, don't worry, but you have to remember that they are not a matter.

=============================================== 线 并 并 发With parallelism] In a single CPU system, the system scheduling can only be run at a moment, although this debugging mechanism has a variety of forms (most of them are the time of the chronograph), but in any case, Switching the thread that needs to be run, makes it in a concurrent. In the multi-CPU system, you can make more than two threads run simultaneously, which can simultaneously run simultaneously in parallel. Parallel). In all the discussion, please understand, I can't use the most accurate words to define such terms, but I will tell you in my experience. How is it? Winning, if you see some of the "Standards" documents I said, just as long as the meaning is consistent, then you don't pick it up. [Java Thread Object] Now let's start to examine the thread objects in Java. In Java To start a thread, there are two ways. First, call the Thread instance's Start () method, the second is to pass the Runable instance to the Thread instance and then call its start () method. In the basic knowledge (1) Over, thread objects and threads are two completely different concepts. Here we re-enter the instance of a thread, does not represent launching threads. The start thread is to start the instance on a thread object. Threads, when the thread is over, it will not disappear immediately. I don't have to say more about the basics you can see from many books. Since it is a basic knowledge, I also focus on can't read from ordinary documents. Content. So this section focuses on the difference between the two thread objects generate threads .class mythread extends thread {public int x = 0; public void run () {for (int i = 0; i <100; i ) ) {Try {thread.sleep (10);} catch (exception e) {} system.out.println (x );}}}}}}}} If we generate an instance of MythRead, then call its start (); method, then The thread corresponding to this example is generated: public class test {public static void main (string [] args) throws exception {mythread MT = N EW mythread (); mt.start ();}} Needless, I will ultimately print 0 to 99, now we play a little pattern: public class test {public static void main (string [] args) throws exception {Mythread MT = New mythread (); mt.start (); system.out.println (101);

}}} It is also not to say, in the basic knowledge (1) we know that due to single CPU, you will generally print 101 first, then print 0 to 99. However, we can control threads to make it up to do in our mean: Public Class Test {Public static void main (string [] args) throws exception {mythread mt = new mythread (); mt.start (); mt.join (); system.out.println (101);}} Ok, we finally See the thread corresponding to the MT instance (if I sometimes say that the MT thread, please don't blame me, but I don't say it as much as possible) After the run is completed, the main thread is printed 101. Because we let the main thread (here the main thread) Wait for the operation of the MT thread. "On the thread object A, the JOIN () method is called, that is, let the currently executive thread wait for thread operations to run until the thread operation is completed," Please have a deep understanding This sentence, and I introduce this knowledge point here to let you continue to look at the following example: public class test {public static void main (string [] args) throws exception {mythread mt = new mythread (); MT. Start (); mt.join (); thread.sleep (3000); mt.start ();}} When the thread object MT is complete, we let the main thread take a break, then start thread on this thread object again. . As a result, we see: Exception in thread "main" java.lang.illegalthreadStateException is also completed in this thread object, it can't run the second time. We can look at it has specific implementation: public Synchronized void start () {if (start) throw new illegalthreadStateException (); started = true; group.add (this); start0 ();} An instance of a Thread once calls a start () method, this instance's STARTED tag It is tagged as true. In fact, there is no matter whether this thread is not executed, as long as it is called again, it doesn't have the opportunity to run, which means: [through the Thread instance Start (), a three instance of a Thread can only Generate a thread] So how should we do if we want to generate multiple threads (the thread pool we often say)? This is the great feature that the runnable interface gives us. Class R imports Runnable { Private int x = 0; public void Run () {for (int i = 0; i <100; i ) {THREAD.SLEP (10);} catch (exception e) {} system.out.println (x ,}}} Is just like its name, the instance of runnable is running, but it does not run directly, it needs to be packaged by the Thread object: public class test {public static void main (String [] Args)................. ..

}} Of course, this result is nothing difference. But if we give a runnable instance multiple packages for the Thread object, we can see that they are actually launching threads on the same example: public class test {public static STATIC Void main (string [] args) throws exception {r = new r (); for (int i = 0; i <10; i ) new thread (r) .Start ();}} x is an instance object, but The result is that X is added to 999, indicating that this 10 thread is running on the same R object. Please note that this example is running on a single CPU, so there is no common object of multiple threads. Synchronization. Here is the convenience of explanation, simplify synchronization, and in the real environment you can't predict that the program will run in any environment, so we must consider synchronization. Here we do a complete example to explain the way the thread is different. The difference between the generated thread: package debug; import java.io. *; Import java.lang.thread; class mythread extends thread {public int x = 0; public void run () {system.out.println ( x );}} Class R Implements Runnable {Private INT X = 0; Public Void Run () {System.out.Println ( x);}} PUBLIC CLASS TEST {public static void main (String [] args) THROWS Exception {For (int i = 0; i <10; i ) {thread t = new mythread (); t.start ();} thread.sleep (10000); // Let the above thread run completed R r = new r (); For (int i = 0; i <10; i ) {thread t = new thread (r); T.Start ();}}} The 10 threads generated above 10 threads are printed at 10 threads. Times 1. 10 thread objects generated below The thread is running from 1 to 10. We call the following 10 threads as multiple threads of the same example (Runnable instance). ==================== ===========================

Several important ways of thread objects Although thread objects can be understood by the API document, there are many ways to explain in detail from the API. Originally intended to use a section of the section to put some important things in the thread method. The knowledge is finished, but it is estimated that it is estimated that it is necessary to use several festivals to say some of the weights related to the thread method. First we take the base article (2) to explain the start () method. After the thread object is generated, if you want to generate a thread, it must call its START () method. If you introduce this method, you have to explain the RUN method. In fact, the RUN method of the thread object is completely an interface callback method, it It is the specific logic of this thread object to be completed. Simply say what you have to do, do you have done in Run, and how to do it, don't need you to control, you only call the start () method, JVM will manage This thread object allows it to generate a thread and how to execute it. From the surface, the start () method calls the Run () method. In fact, the start () method does not call the RUN method directly. In JDK1. 5 Previous () method is the local method. How do it eventually call the RUN method is no longer what the Java programmer can understand. In JDK1.5, the original local START () method is replaced by START0 (), one Pure Java's start () is called local method START0 (), and a verification is made in the start () method is to test a global variable (object variable) Started. If true, start () throws an exception. Do not call local methods Start0 (), otherwise, first set this variable, then call start0 () we can see this to control a thread object only START () method. This is because The thread runs to obtain the current environment, including the security, parent thread permission, priority, etc. If a thread object can run multiple times, then define a Static thread to get the appropriate permissions and priority in an environment, after running It uses the original permissions and priority and other properties to run in the current environment in another environment, which causing the unpredictable result. Simply, let a thread object can only run once, based on the need for thread management The most essential functionality of the .start () method is to apply for another thread space from the CPU to execute the code in the Run () method. Its and the current thread are two lines, which is running relatively independent threaded space, that is, If you call the Run () method of the thread object directly, it will also be executed, but that is executed in the current thread, the run () method continues to perform the following code after execution. And after calling the start () method, Run () Method code and current line Cheng Ming (single CPU) or parallel (multi-CPU) is executed. So remember that a sentence [The RUN method of calling the thread object does not generate a new thread], although the same execution result is reached, but the execution process and execution efficiency Different. [Interrupt () method, interrupted () and isinterrupted ()] These three methods are very close and complicated, although their respective features are clear, but they have most people Not a real understanding. Let's talk about the interrupt () method, it is an example method, and it is also the most strange way, in the Java language, thread is initially designed to "indiscriminately understand"

Things until it is now, it is not as accurate like its name. Most people think that a thread icon calls the interrupt () method, the corresponding thread should be interrupted and throwing an exception, the facts, when A thread object calls an interrupt () method, its corresponding thread is not interrupted, just changing its interrupt status. Make the status of the current thread to the interrupt state, if there is no other impact, the thread will continue to execute. Just When the thread performs a method such as Sleep, Wait, Join, or if you check the interrupt status, threads will throw an exception. If the thread object calls interrupt (), its corresponding thread is interrupted immediately, then Interrupted () The method is impossible. Because the interrupted () method is a Static method, that is, it can only be called on the current thread, and if a thread interrupt () has been interrupted, then how it makes itself interrupted () ? Just because a thread calls interrupt (), it only changed the interrupt state, it can continue to execute, before you call Sleep, Wait, Join, etc., it can call Interrupted () to clear the interrupt status before you don't call Sleep, Wait, JoIn. (Also original) Interrupted () method checks the interrupt state of the current thread. If "Interrupt Status" changes the current thread is "non-interrupt state" and returns true if it is "non-interrupt state", it returns false, it Not only is the current thread is an interrupt state, but it is called "interrupted", which is called "interrupted", which is said that the interrupt status has ended (to non-interrupt state) isInterrupted () method only checks the thread object. Whether the thread is an interrupt state and does not change its state. At present, you can only remember the functions of these three methods. Only if you really go into multi-threaded programming practice, you will experience why they are object methods, why is it? Class Method. When is the thread to be interrupted to throw an interruptedException, we will discuss in detail in the improvement. [Sleep (), Join (), Yield () method] In the current situation, I can only explain these The method of the method and the principle of calling, as for why, in the basic article, it cannot be in-depth in the basic article. It can only be described in detail. The Sleep () method is a class method, that is, for the current thread, the programmer cannot specify a certain Thread go to sleep, only when the current thread is executed to the SLEEP () method, the time (let other thread runs). In fact It can only be a class method, call on the current thread. Imagine if you call a Sleep () method of a thread object, if this object is not running, how do I sleep ()? So only the current thread, because it Being executing, you can guarantee that it can call the Sleep () method. Principle: Do not call the Sleep () method of the thread in the synchronization method], or briefly, for the general level of programmers, you should not call SLEEP () Method. JOIN () method, as in the first section, call the Join method on a thread object, is the end of the thread that is waiting for this thread object, such as two work, working A to consume 10 seconds, Work B is 10 seconds or more. We made a thread in the program to do work B, then do work A.NEW B (). Start (); // Do work Ba ​​(); // Do work A After the work A is completed, the results of the work B will be processed below. If the work B has not completed the following work C, B B b = new b (); b.Start (); // Work BA (); // Do work ab.join (); // and other work B complete .c ();

// Continue Work C. Principle: [Join is the only correct way to test other working status], I have seen many people, and even some doctoral students, if another work is not completed while dealing with a job, saying that the current work Thread Sleep (x), I asked him, how do you specify this x, how do you know that it is 100 milliseconds instead of 99 milliseconds or 101 milliseconds? In fact, this is the essence of the ONXXX event, we don't want to wait for a long time What to do, but when you wait for the work just complete? Yield () method is also a class method, only calls on the current thread, the reason is the same, it is the principle of the current thread to give this assignment : [Not very necessary, there is no reason to call it]. Calling this method does not increase any efficiency, just reduce the thread of the CPU's total cycle, based on the (basic article), only simply mention I will discuss in conjunction with examples later. For other methods of thread itself, please refer to the API document. The next section introduces the non-thread method, but the thread is closely related to the two [three] object methods: [Wait (), Notify () / notifyAll ()] ============================================= ====

[Wait (), notify () / notity () method] About these two methods, there are many contents need to be explained. In the following description, there may be many places that can not be understood, but after reading this section, Even if you can't fully understand, you must return to your head to remember the following: [Wait (), notify () / notityAll () method is a normal object method (Implemented in the Object Semiology), not thread objects Method] [WAIT (), Notify () method () method can only call] [Mutual exclusion control of threads] when multiple threads operate in a synchronization method, the operation of the object may Change its status, and this state will affect the true result of another thread on the object. This example we can see in too many documents, just like two of the two-course ticket staff sell the same ticket. Thread a thread B1 Thread A Query the ticket in the database, discovering the ticket C can be sold 2. Thread A accepts the user's booking request, ready for the ticket .3. Switch to the thread B execution 4. Thread B In the database, check the ticket, Discover the ticket C can be sold 5. Thread B sells the ticket out 6. Switch to thread a execution, thread a sells a ticket that has been sold, so it needs a mechanism to manage this problem, when a certain The thread is executing an indivisible portion, and other threads cannot implement this part at the same time. I only have one thread to perform a mechanism for executing an execution unit called mutex or sharing mutual exclusion (MUTUAL EXCLusion) In Java, use Synchornized keyword to implement mutual exclusive control (temporarily thinking, JDK1.5 has developed new mechanism) [Synchornized keyword] State a unit as synchornized, you can make only one thread at the same time Operation This method. Some people say that synchornized is a lock, in fact it does exist, but who is lock, lock who is a very complex problem. Each object is only a monitor lock (Monitor Lock). Once you can get one thread. When a thread gets this lock, other threads can only wait for this thread release lock to get it again. What is the Synchornized keyword to lock? What is the lock? For synchronization block, Synchornized is the object lock in the parameter: Synchornized (obj) {/// ...............} When the thread is executed, you must first get the lock of the OBJ, if not Getting thread can only wait. If multiple threads are executed here, only one thread gets OBJ lock, then the statement in {}, so the role of the OBJ object is different, the control program is different. If: public void Test () {Object O = New Object (); Synchornized (OBJ)}} This program does not control any, multiple threads are executed Object o = new object (); each generates an object then obtains this object has a monitor lock, and each is full of joy. And if it is an attribute: Class test {Object O = New Object ();

Public void test () {synchornized (o) {// .............}}} All Synchornized (o) of the Test instance, only one thread can get Monitor lock. Sometimes we will this: public void test () {synchornized (this) {// .............}} The thread that implements TEST instances can only have a thread. Execution. The range of Synchornized (O) and Synchornized (this) is different, because the Synchornized (O) of the Test instance is performed, other threads can perform the SYNCHORNIZED (O1) section of the Test instance, but multiple threads There is only one Synchornized (this) that can perform Test instances. For synchornized (test.class) {/// .............} All call TESTs The thread enlightencousness of multiple instances can only be executed. [Synchornized method] If a method declares as synchornized, it is equivalent to calling Synchornized (this) on a method. If a static method is declared as synchornized, Then I can call Synchornized (class .class) on a method. Now enter the WAIT method and Notify / NotifyAll method. These two (or three) methods are Object object methods, rather than thread objects. Like the lock, they are called on a target in a thread. Class test () {public synchornized void test () {// Get condition, INT X requires greater than 100; if (x <100) Wait ();} } Here is not added to TRY {} cat CH () {}, if there is no clear () method to call on which object is called, this.wait (); if: test t = new test (); now there are two threads to execute to T. Test Method. The thread A acquires T's object lock, into the TEST () method. At this time, the X is less than 100, so the thread A enters the waiting. After a thread is called, this thread has entered this object. The lounge (Waitset), this is a virtual object, but there must be such a data structure in the JVM to record which of the current objects are waiting. When a thread goes to wait, it will release the lock, let Other threads get this lock. So thread b has the opportunity to get the lock release of thread a, enter the test () method, if X or less than 100, thread B also enters the T's lounge. These two threads can only Waiting for other thread calls notity [all] to wake up. But if the call is a parameter, the thread A, B will wait for this time after the lounge is automatically awakened. [Why is the real app use While (condition) without if (condition)] We see a large number of examples in actual programming, use While (x <100) Wait (); go (); not use IF, why? In multiple When thread is executed simultaneously, if (x <100) is unsafe. Because thread a and thread b wait in the lounge of T, then another thread makes x ==

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

New Post(0)