A thread is an abstract concept that allows parallel computing: when another thread completes a computing task, a thread can update the image, two threads can simultaneously process two network requests from the same process. Here we areArticleWe will focus on the differences between Java and C # threads, and convert the common patterns of some java threads to C #.
In terms of concept, threads provide a type of parallel execution in a softwareCodeIn this way, every thread executes commands "simultaneously" in a shared memory space (of course, on a processor, this is done through the alternate execution of running threads .), Therefore, each thread can accessProgramData structure. For this reason, the difficulty of multi-threaded programming can be imagined, because there are many different threads in a program that need to securely share data.
Thread creation and running
Java provides most of the thread functions in the Java. Lang. Thread and Java. Lang. runnable classes. It is very easy to create a thread, that is, to extend the Thread class and call start (). You can also define a thread by creating a runnable () class and passing it as a parameter to thread. Carefully read the following simple Java program. Two threads are simultaneously counting from 1 to 5, and the results are printed.
Public class threadingexample Extends object { Public static void main (string ARGs []) { Thread [] threads = new thread [2]; For (int count = 1; count <= threads. length; count ){ Threads [count] = new thread (New runnable (){ Public void run (){ Count ();
}
}); Threads [count]. Start ();
}
}
Public static void count (){ For (int count = 1; count <= 5; count) System. Out. Print (count "");
}
} |
We can use the system. Threading. Thread and system. Threading. threadstart classes to convert the above Java program to the C # language:
Using system. Threading; Public class threadingexample: object { Public static void main (){ Thread [] threads = new thread [2]; For (int count = 1; count <= threads. length; count ){ Threads [count] = new thread (New threadstart (count )); Threads [count]. Start ();
}
}
Public static void count (){ For (int count = 1; count <= 5; count) Console. Write (count "");
}
} |
There are some tips in this example. Java allows extension of the Java. Lang. Thread class and execution of the Java. Lang. runnable interface. C # does not provide us with such convenience. A thread object in C # is unknown and must be created through threadstart. This means that the internal class mode cannot be used, but an object must be created, in addition, the method must be passed to an object of the thread for thread execution.
Thread usage
Many programmers in Java want to perform standard operations on a thread, such as testing whether a thread exists, adding a thread until it dies, and killing a thread.
Table 1: Functions managed by threads
Comparison Between Methods in Java. Lang. Thread in Java and system. Threading. Thread objects in C.
Setdaemon (Boolean on) Method
Isbackground setting attribute values
Make an existing process a new thread (if all the remaining processes become new threads, the program stops running ).
Isdaemon () method
Isbackground get attributes
If the thread is a background thread, the true value is returned.
Isalive () method
Isalive get attributes
If the thread is active, the true value is returned.
Interrupt () method
Interrupt () method
In Java, this method can be used to set the thread interruption status and to check whether the thread is interrupted. There is no corresponding method in C #. Executing the interrupt method on a thread that is not in the blocking status will automatically invalidate the next blocking call.
Isinterrupted () method
N/
If the thread is in the blocking status, the true value is returned.
Sleep (long millis) and sleep (long millis, int Nanos)
Sleep (INT millisecondtimeout) and sleep (system. timespan) Methods
Pause the thread that is being executed for a specified period of time, or wait until it is interrupted. This method will generate a java. Lang. interruptedexception state in Java, and system. Threading. threadinterruptedexception state in C.
Join (), join (long millis), and join (long millis, int Nanos) Methods
Join (), join (INT millisecondtimeout) and join (system. the difference between the timespan method and Java is that, in C # language, the thread stops running because the thread is dead (returns true) or times out (returns false) returns a Boolean variable.
Suspend () method
Suspend () method
The two functions are the same. This method can easily lead to an endless loop. If a thread that occupies the critical resources of the system is mounted, other threads cannot access the resource before the thread resumes running.
Resume () method
Resume () method
Resume a suspended thread.
Stop () method
Abort () method
See the "thread stop" section below.
(Note: in the preceding table, the first row of each section is the method in Java, the second row is the method in C #, and the third row is the related annotation, because tables cannot be organized in text files, edit the multi-expense organization table. The original text contains the table format .)
Thread Suspension
Thread. Stop in Java has been widely opposed because it can bring the running program into a disordered state without any warning. According to the call stop () method, an unchecked Java. lang. the threaddeath error will damage the stack of the running program. As it continues to run, it can remove any locked objects. As these locks are opened indiscriminately, the data they protect is very likely to be in disorder.
According to the current Java document, the recommended way to abort a thread is to let the running Thread Check a variable that can be changed by other threads, which represents a "Dead Time" condition. The following program demonstrates this method.
// condition variable private Boolean timetodie = false; // check the conditional variables in each iteration. class stoppablerunnable extends runnable { Public void run () { while (! Timetodie) { // perform the corresponding operation } |
The above discussion also applies to the abort method in C. According to the called abort method, it is an unpredictable system. threading. threadabortexception may damage the stack of the thread. It may release some variables maintained by the thread and cause unpredictable errors to the data structure in the protected State. I suggest using a similar method as shown above to notify a thread that should die.
Thread Synchronization
In terms of concept, threads are very easy to understand. In fact, since they may interact with the same data structure, they become a headache for programmers. Take threadingexample as an example. When it runs, multiple different results will be output on the console. From 1 2 3 4 5 1 2 4 5 to 1 1 2 2 3 3 4 4 5 5 or 1 2 2 2 3 3 4 4 4 5 may occur, the output result may be related to the difference in the thread scheduling mode of the operating system. Sometimes it is necessary to ensure that only one thread can access a given data structure to ensure the stability of the data structure. This is also the reason why we need the thread synchronization mechanism.
To ensure the stability of the data structure, we must use the "Lock" to adjust the operation sequence of the two threads. Both languages apply for a "lock" for the referenced object. Once a program obtains control of the "lock", it can ensure that only it obtains the "lock ", this object can be operated. Similarly, with this lock, a thread can remain in the waiting state until it can wake up its signal to pass through the variable.
Table 2: Thread Synchronization
Key words to be mastered during Thread Synchronization
Synchronized
Lock
The lock command in C # is actually used for the syntax of the enter and exit methods in the system. Threading. Monitor class.
Object. Wait ()
Monitor. Wait (Object OBJ)
C # does not have a method to wait for an object. If you want to wait for a signal, you need to use the system. Threading. Monitor class. Both methods must be executed in the synchronization program segment.
Object. Policy ()
Monitor. Pulse (Object OBJ)
See the preceding monitor. Wait annotations.
Object. Policy ()
Monitor. pulseall (Object OBJ)
See the preceding monitor. Wait annotations.
(Note: in the preceding table, the first row of each section is the method in Java, the second row is the method in C #, and the third row is the related annotation, because tables cannot be organized in text files, edit the multi-expense organization table. The original text contains the table format .)
We can make some appropriate modifications to the above example. By adding a variable for synchronization, and then modifying the count () method as follows, add 1 to the variable in the lock.
Public static object synchronizevariable = "locking variable ";
Public static void count (){ Synchronized (synchronizevariable ){ For (int count = 1; count <= 5; count ){ System. Out. Print (count ""); Synchronizevariable. policyall (); If (count <5) Try { Synchronizevariable. Wait ();
} Catch (interruptedexception error ){
}
}
}
} |
After the preceding changes, only one thread (because only one thread can obtain synchronizevariable at a time) can execute the for loop to output the number 1. Then, it will wake up all threads waiting for synchronizevariable (although no threads are waiting yet .), And try to get the locked variable, and then wait for the lock variable to be obtained again; the next thread can start to execute the for loop to output the number 1 and call yyall () to wake up the previous thread, and make it start to try to get the synchronizevariable variable, put itself in the waiting state, release synchronizevariable, and allow the previous thread to get it. This loop continues until all of them output numbers from 1 to 5.
Through some simple syntax changes, the above modifications can be implemented in C:
Public static object synchronizevariable = "locking variable ";
Public static void count (){ Lock (synchronizevariable ){ For (int count = 1; count <= 5; count ){ System. Out. Print (count ""); Monitor. pulseall (synchronizevariable ); If (count <5) Monitor. Wait (synchronizevariable );
}
}
} |
C # Special Thread Functions
As we have always expected for C #, C # does have some methods, classes, and functions that are not supported by Java. For hardcore Java thread programmers, this is a good thing, because they can write code in C # And then reference it in Java code.
Enter/tryenter/exit
To obtain the Lock of a variable in Java, you must add the synchronized key at the beginning and end of the Code to specify the object to be locked. Once the thread starts executing the code in the synchronized block, it gets control of the lock on this object. Similarly, once the thread has left the synchronized block, it will release the Lock of this object. We already know that C # has a similar word called lock. In addition to lock, C # also provides the built-in method for obtaining and Releasing locks: Monitor. enter (Object OBJ) and monitor. exit (Object OBJ). By using these methods, programmers can obtain the same effect as using lock, but provide more precise control methods. For example, you can lock several variables in a method and release them at different times or in different parts of the Code.
If the system. Threading. Monitor. Enter operation is performed on an object to be synchronized, the thread can obtain the lock of the object or block the lock of the object controlled by other threads. Execute the monitor. Exit method to release the lock. If the thread does not control the Lock of this object, this method will generate a system. Threading. synchronizationlockexception signal.
The monitor class in C # includes not only the enter method, but also the tryenter method. If you execute this method, a lock will be obtained or a return value indicating that it cannot obtain the lock.
Atomic operation
System. threading. the interlocked class provides the program's ability to synchronously access the variables shared by several threads. C # abstracts some operations into "Atomic" operations or "inseparable" operations. To illustrate how this problem is solved, let's look at the following Java code:
Public static int x = 1;
Public static void increment (){ X = x 1;
} |
If two different threads call increment () at the same time, the final value of X may be 2 or 3. The cause of this situation may be that the two processes access the X variable unordered, if the value of X is not set to the initial value, add 1 to it. Before the value of 1 is added to X in any line, both threads may read X as 1, and set it to a new value.
In Java and C #, we can implement synchronous access to the X variable, and all processes can run in their own way. But by using the interlocked class, C # provides a more thorough solution to this problem. The interlocked class has some methods, such as increment (ref int location) and decrement (ref int location). Both methods obtain integer parameters, add or subtract 1 to the integer and return a new value. All these operations are performed in an "inseparable" manner, in this way, you do not need to create an object for synchronization, as shown in the following example:
Public static object locker =... Public static int x = 1;
Public static void increment (){ Synchronized (locker ){ X = x 1;
}
} |
The interlocked class in C # can use the following code to perform the same operation:
Public static int x = 1; Public static void increment () { interlocked. increment (ref X); } |
interlocked also contains a method named "Exchange". You can set the value of a variable to the value of another variable in an "inseparable" manner.
thread pool
if many applications that use threads create threads, these threads will waste most of their time waiting for certain conditions (such as the keyboard or new I/O input. threading. the threadpool object can solve this problem. With threadpool and event-driven programming mechanism, the program can register a system. Threading. waithandle object (waithandle is the object model of the wait and notification mechanism in C # programming .) And system. threading. waitortimercallback object. All threads do not need to wait for the release of waithandle. threadpool monitors all waithandle registered with it, and then calls the corresponding waitortimercallback object method after the waithandle is released.
conclusion
In this article, we briefly discuss the mechanism provided by C # For threads and parallel operations, most of them are similar to Java except for Objective C #. They provide thread objects that can run the provided methods and synchronous methods for code access. Similar to other aspects, C # also provides some unsupported Java syntaxes in terms of threads (to some extent, some underlying contents of synchronization operations are revealed .), Java programmers may find this part very useful.