In the last section of the line program (click here for details), we explain the thread waiting for join (), the daemon thread. In this section we will complete the rest of the thread control content, the main content of the threads of sleep, concession, priority, suspend and resume, stop and so on.
Needless to say, we go straight to the chase:
3. Sleep on Thread sleeping ()
All of the learning cases that introduce multithreaded development are basically useful to this method, which means sleep (it is true, please believe me ...) )。 Well, if you feel that it is not specific enough, you can think of the current thread to pause, the current thread goes into a blocking state, when the sleep time is over, the current thread re-enter the ready state, start a new round of preemption plan!
So what is the use of this approach in real-world development? I give an example, in many cases, the current thread does not need real-time monitoring or is running, but will periodically check whether a state is standard, if it meets the departure conditions, then do one thing, or continue to sleep. For example, in a heartbeat mode, we send a daemon thread to the server for data requests, and when we receive a response, we sleep for a while, and when we wake up again, we continue to send such requests. Real-life examples, such as whether we are waiting for a TV to launch, but do not want to see the previous ads, so we may wait a while to switch the TV channel to the location to play a look, if the ads are still playing, then we will jump to other channels to watch, and then periodically switch to the target channel to view.
The code is as follows:
1 Public classThreadstudy2 {3 Public StaticMain (string[] arg)throwsException4 {5 for(inti=0;i<=1000;i++)6 {7 if(Isinternetaccess ())8 {9Thread.Sleep (1000*6);//Watch this .Ten } One Else A { -System.out.println ("error! Can not Access internet! ") - Break; the } - } - } - PrivateBoolean isinternetaccess () + { - //Bala Bala + return true; A } at}
The code means to check whether the network is unobstructed, if it is unobstructed then go to sleep, sleep 6 seconds after waking up again for a check. By allowing the thread to sleep, we can allocate resources efficiently, allowing other threads to get CPU resources faster at leisure. One thing to note here is that after a thread sleeps, it goes into a blocking state (whether or not the CPU is idle at this time, it will still be paused, is mandatory), when the sleep time is over, enter the ready state, need to compete again to preempt the CPU permissions, and not immediately after the end of sleep can execute the method. So the actual interval is greater than or equal to the time of sleep.
The Java thread class provides two static methods to pause a thread
1 Static void sleep (long millis) 23 staticvoid Sleep (long millis,int Nanos)
Millis is milliseconds, Nanos is microseconds, and is similar to thread join (), because of JVM and hardware, we also use Method 1 basically.
4. Thread Concession yield ()
In life we have encountered such an example, in the bus, the subway to make a quiet Adonis (or female men), at this time came in an old man, pregnant women, you stand up silently, the seat to the elderly. Go to the side and wait for the new vacant seat. Or you play computer games silently, then your mother loudly shout your full name (yes, is the full name), this time your first reaction is, I did something wrong, the second reaction is to put down the mouse on the hand, obediently run to your mother to accept the reprimand. All of this is due to the urgency of the matter. The thread currently being processed is shelved, and we (the CPU) handle the current emergency transaction. In software development, there are similar scenarios, such as a thread processing of the task is too large, the other threads are always unable to preempt the resources, this time we have to take the initiative to make concessions to other threads a fair preemption opportunity.
Here is a picture from the Web: When we are strong, we should give the weak a chance. Cough back to the chase.
Here is the code
1 Public classTestthreadextendsThead2 {3 PublicTestthread (String name)4 {5 Super(name);6 }7 8 Public voidRun ()9 {Ten for(inti=0;i<=1000000;ii++) One { ASend ("Msgbody"); - if(i%100==0) - { theThread.yield ();//Watch this . - } - } - } + - Public Static voidMain (string[] args)throwsException + { ATestthread thread1=NewTestthread ("Thread1"); atThread1.setpriority (thread.max_priority);//Watch this . - -Testthread thread2=NewTestthread ("Thread2"); -Thread1.setpriority (thread.min_priority);//Watch this . - Thread1.start (); - Thread2.start (); in } -}
After we start the thread, we pause the current thread once every 100 messages are sent, leaving the current thread in a ready state. At this point the CPU recalculates the priority and selects the higher priority to start.
Compare the sleep method and the yield () method here.
(1) After the sleep method pauses the thread, the thread goes into a blocking state (even for an instant), and at this point the CPU selects only the thread that is already ready, so it does not select the thread that is currently sleeping. (even if there are no other threads available). The yield () method causes the current thread to immediately enter a ready state, in the range of optional threads selected by the CPU, containing the thread that currently executes the yield () method. If no other thread has a higher priority than (or equal to) yield (), the CPU will still select the original yield () thread to restart.
(2) The Sleep method throws a Interruptedexception exception, so calling the sleep method needs to declare or catch the exception (which is cumbersome than C # handles the exception), and yield does not declare an exception to be thrown.
(3) Sleep method of good transplant, can correspond to many platforms of the underlying method, so the place to sleep () to excess yield () place;
(4) After sleep pauses a thread, the thread sleeps for a certain amount of time before it becomes ready, and if it is defined as sleep (0), then the blocking state is 0 and immediately ready, and this usage is essentially the same as yield (): That is, the CPU makes a new selection, Avoid the current thread over-hogging the CPU, causing the program to feign animation.
The biggest difference between the two methods is that sleep throws an exception that needs to be handled, and yield () does not; And the tiny difference between the two is different in each version of the JDK, so look at this question on StackOverflow: is Thread.Sleep (0) and Thread.yield () statements equivalent? (click here to enter)
5. Priority setting for Threads
The priority of a thread is equal to the weight of an opportunity, and the higher the priority, the more likely it is to get an execution opportunity, and the less likely it is to get an execution opportunity. (Remember that the probability is greater or smaller).
In this section of the thread concession this part of the code we have shown in code how to set the priority of the thread here does not do special code presentation. (Anti-Theft connection: This article starting from http://www.cnblogs.com/jilodream/)
Thread gives us two ways to set and get the priority of a thread, respectively.
1 setpriority (int newpriority)2 getpriority ()
SetPriority to set the priority, the value range of the parameter is before 1~10.
Three static constants are also set:
tread.max_priority=10;
tread.norm_priority=5;
Tread.min_priority=1;
Although Java provides 10 priority for threads, the underlying platform threads tend not to have a 10 priority, resulting in a relationship that is not meant to correspond. (for example, the OS has only five priorities, so that each two priority only corresponds to one OS priority). At this point, we often use only these three static constants to set the priority, rather than specifying the specific priority value (because there may be multiple priorities corresponding to a certain priority of the OS), causing unnecessary trouble.
In addition, the default priority for each thread is the same as the priority of creating his parent process, and by default the main thread has a normal priority, so the new thread created by the code above defaults to the normal priority.
The following is the focus of the priority concept:
In fact, the priority you set does not really represent the priority of the thread or the boot, which is just a reference to the calculation priority when the OS starts the thread. The OS will also see if the current thread is hogging the CPU for a long time, and if so, the OS will moderately increase the priority of other "hungry" threads. Forced suspend for those threads that have been hogging the CPU for a long time. Making this setting simply increases the chance that the thread will be executed in some way. In fact, those long-term occupation of the CPU thread is not a single occupation of the time is long, but is continuously selected situation is very many, resulting in a long-term occupation of the illusion.
So after you set the priority, the order in which the threads actually execute is not predictable, or even a bit confusing . With this in mind, we are developing a multi-threading system that does not fully expect to have a simple set-priority to schedule the execution of threads.
Two articles are referenced here, for more details, please refer to the original text:
(1) Java multithreading--Thread Priority (original link)
(2) The meaning of Thread.Sleep (0) (original link)
6. Force End Thread Stop ()
Sometimes we find that there are some running threads that are no longer necessary to continue, but there is a period of time between the end of multithreading and we need to force the end of multithreading. Java used to provide a method stop () dedicated to end the thread, but this method has now been deprecated and is not recommended for developers.
This is due to the inherent insecurity of this method. Using Thread.stop to end a thread, the JVM forces the release of all objects it locks. When the state of an object is not consistent at some point (in the process of processing a transaction), it can cause many unintended consequences if the object is forcibly disposed. The specific point is that the system generates a Threaddeath exception at the top of the stack of the locked resource. This unchecked Exception will silently shut off the associated thread. The data inside the object may be inconsistent, and the user will not be alerted to any inconsistent objects. The consequences of this inconsistency will only be discovered in the course of future use, which has resulted in unforeseen consequences.
Some people might consider avoiding this form by calling the Stop method and then capturing the form of Threaddeath. This idea seems to be achievable, in fact, because threaddeath this anomaly may be thrown in any position, need and careful consideration. And even with that in mind, the system might throw a new threaddeath when the exception is caught. So we should kill this way at the source, rather than fix it through constant patching.
So the question is, if we really want to shut down a thread, what should we do with it?
With the Stop method we can see that it is often difficult to handle the problem of data consistency and the internal running process of threads when threads are closed externally. Then we can determine whether to continue running by setting the Always flag variable, and then periodically checking whether the variable is an end identifier.
For example, I have written a thread that monitors computer metrics. This thread periodically checks the state variables in the cache. This state cache can be set externally. When the thread discovers that the variable has been set to "end", the remaining work is handled internally and runs directly through the Run method.
7. Thread suspend and resume suspend ( ) and resume ()
We sometimes need to suspend the thread, and the time to suspend is unclear, and it is possible to notify the thread to start working under some future condition. Java provides us with two ways to do this:
Suspend suspend ()/Resume resume.
We already know by the title that these two methods are also not recommended by Java, but why?
Suspend is to suspend the current thread directly into a blocking state, while not modifying his internal control and locked resources (this is similar to the Stop method, where it is often difficult to see the state of the internal run and the resources under control, so it is difficult to handle). So that the suspended thread locked resources can no longer be accessed by other resources, resulting in a state of suspended animation lock. A real lock is formed when the thread is restored (resume) and the resources in the hand are freed, and other threads can re-access the resource, but if the other thread is resuming (resume) suspended (suspend) thread, it needs to access the locked resource first.
So the question is, if we really want to hang up a thread, what should we do with it?
In this same vein as stop (), we can set an identity inside a thread that may be suspended, indicate whether the thread is currently pending, and if the variable indicates to be suspended, use the wait () command to enter the wait state, and then wake the thread with notify () if the identity indicates that the thread can be recovered. (These two methods will be explained in the thread communication later in this article).
Two articles are referenced here, for more details, please refer to the original text:
(1) Why the use of Thread.stopsuspend and Resume () (original link) is not supported
(2) The non-security of the JAVA Stop method (original link)
Java Multithreaded Development Series four: Topsy-Threading (Threading Control 2)