I. The state of 1. The concept of the state of being
The correctness of the calculated results depends on the relative time sequence and the interleaving of threads, the popular saying is that the calculation results are related to time, and for a similar input, sometimes the results are correct, sometimes the results are incorrect.
The state of being does not necessarily lead to a result error, but to the possibility that this results in an error.
2. Simulation of the emergence of the state
Below is a mock Request ID generator that allows multiple threads to randomly generate a request ID.
PublicFinalclassRequestidgenerator {PrivateFinalStaticRequestidgenerator INSTANCE =NewRequestidgenerator (); PrivateFinalStatic ShortSeq_upper_limit =999; Private Shortsequence =-1; PrivateRequestidgenerator () {} Public Staticrequestidgenerator getinstance () {returnINSTANCE; } Public Shortnextsequence () {if(Sequence >=seq_upper_limit) {Sequence=0; } Else{sequence++; } returnsequence; } PublicString NextID () {SimpleDateFormat SDF=NewSimpleDateFormat ("Yymmddhhmmss"); String TimeStamp= Sdf.format (NewDate ()); DecimalFormat DF=NewDecimalFormat (" the"); ShortSequenceno =nextsequence (); return "0049"+timestamp+Df.format (Sequenceno); }}
View Code
Test class:
Public classRaceconditiondemo { Public Static voidMain (string[] args) {intNumberofthreads =runtime.getruntime (). Availableprocessors (); Thread[] Workthreads=NewThread[numberofthreads]; System. out. println (numberofthreads); for(inti =0; i< numberofthreads; i++) {Workthreads[i]=NewWorkerthread (I,Ten); } for(Thread t:workthreads) {T.start (); } } Static classWorkerthread extends Thread {PrivateFinalintRequestCount; PublicWorkerthread (intIdintRequsetcount) {Super ("worker-"+ID); This. RequestCount =Requsetcount; } @Override Public voidrun () {inti =RequestCount; Requestidgenerator Generator=requestidgenerator.getinstance (); while(i-->-1) {String RequestID=Generator.nextid (); ProcessRequest (RequestID); } } Private voidProcessRequest (String RequestID) {tools.randompause ( -); System. out. println (Thread.CurrentThread (). GetName () +" "+RequestID); } }}
View Code
It is supposed that the request IDs generated by each thread at different times should be different, but multiple executions will find that sometimes the request ID is the same.
This means that the execution result is correct or not and time-dependent, that is, the occurrence of the state.
3. Analysis of the results of the condition
Analysis visible NextSequence () This method causes different threads to get the same RequestID because Requestidgenerator has a shared global variable sequence, multiple threads concurrently reading updates
Sequence led to the appearance of the state. that is, one thread's updates to sequence may be overwritten by updates from other threads, causing the data to be dirty-read.
4. Two modes of the state①read-modify-write (read-change-write)
That is to read the value of a shared variable (read), then make some calculations based on the value (modify), and finally update the value of the variable (write).
For example sequence++ is the case, the process instruction is as follows:
1. Read the value of squence from memory into register R1
The value of 2.R1 plus 1
3. Update the value of R1 to the memory space of the sequence variable
In a multithreaded environment, when a thread finishes executing 1, it is possible that other threads have updated the value of sequence, but the thread still uses R1 values that are not updated to manipulate 2, 3 instructions, resulting in lost updates and dirty reads.
②check-then-act (Detect and then move)
Take the following code as an example:
Public Short nextsequence () { if (sequence >= seq_upper_limit) { //step 1 0 ; Step 2.1 else { sequence+ +; Step 2.2 } return sequence; }
The detection and subsequent action refers to reading the value of a shared variable, making some judgments based on that value, and then performing some actions based on the result of the decision.
In a multithreaded environment, it is possible that when a thread finishes executing step 1, the other thread updates the value of sequence, and the thread still does some work based on the previous judgment, causing the loss of data updates and dirty reads.
The State of multithreading programming