Thread safety [repost]

xiaoxiao2021-03-06  66

[Repost] http://blog.9cbs.net/wjmmml/archive/2004/11/11/177317.aspx

Four ways Sychronized keyword

Sychronized method () {} sychronized (ObjectReference) {/ * block * /} static synchronized method () {} sychronized (classname.class)

Where 1 and 2 are representative lock current objects, that is, an object is a lock, 3 and 4 representative locks, that is, the lock of this class should be noted that sychronized method () is not locking this function, but a lock object, ie: If there are two methods in this class, it is sychronized, then as long as there are two threads share a Reference Reference, one of these two methods, regardless of whether it is the same method, it will be synchronized with this object lock. The 3 and 4 classes of the lock, that is, the different reference of this class calls the Sychronized section of the Sychronized section. It is also controlled by the class lock. If the order of the two functions calls cannot be interrupted, then there is a special Lock object to complete this task: class mylock {synchronized getLock () {// #### has not been written}}

Five levels see Effective Java Item 52: Document Thread Safety

Immutable Unremntered Object Thread-Safe Thread Security, you can use, such as java.util.timer conditionally thread-Safe condition thread secure, such as Vector and HashTable, generally secure, unless there are several method calls Can't be interrupted, you can use the additional lock to complete thread-compatible to help complete the call to thread through Thread-hostile is not safe.

Wait & NotifyAll

Use WAIAll in the cycle instead of notify

Pipe

There is also a PIPE in Java, four classes: PipedinputStream, PipedInputReader, PipedputStream, Pipedputstream, below is the code of producer consumers (from Core Javaii):

/ * Set up pipes * / PipedOutputStream pout1 = new PipedOutputStream (); PipedInputStream pin1 = new PipedInputStream (pout1); PipedOutputStream pout2 = new PipedOutputStream (); PipedInputStream pin2 = new PipedInputStream (pout2); / * construct threads * / Producer prod = New Producter (Pout1); Filter Filt = New Filter (PIN1, Pout2); Consumer Cons = New Consumer (PIN2); / * START THREADS * / PROD.START (); Filt (); Cons.Start ();

note

Long and double are two special 咚咚: Java reads them twice, so you need to synchronize deadlocks is a classic multi-threaded problem, because different threads are waiting for locks that are not possible at all. Resulting in that all work cannot be completed. Suppose there are two threads, representing two hungry people, they must share the knife and fork and take turns. They all need to get two locks: shared knives and locks of shared forks. If the thread "a" gets a knife, the thread "b" has obtained fork. Thread A will enter the blocking state to wait for the fork, and the thread B is blocked to wait for the knife from the A. This is just an example of artificial design, but although it is difficult to detect during runtime, this type often occurs. Although it is very difficult to detect or scrutinize the various situations, as long as the system is designed according to the following rules, it is possible to avoid deadlocks:

Let all threads get a set of locks in the same order. This method eliminates the problem of the resources of X and Y wait for the other party's resources. Multiple locks form a group and put it in the same lock. In the example of deadlocks, you can create a lock of a silver object. The lock must be obtained before obtaining a knife or fork. The available resources that will not be blocked can be marked. When a thread gets a lock of the silverware object, you can judge whether the object lock in the entire silver collection can be obtained by checking the variable. If so, it can get the associated lock, otherwise, it is necessary to release this lock of the silverware and try again later. Most importantly, carefully designing the entire system carefully before writing code. Multithreading is difficult, and the detailed design system can help you to discover deadlocks before starting programming.

Volatile variable. Volatile keyword is a Java language for optimizing compiler. The following code is:

Class volatiletest {

Public void foo () {

Boolean flag = false;

IF (flag) {

// this could happen

}

}

}

An optimized compiler may determine whether the statement of the IF section will never be executed, and this part is not compiled. If this class is accessed by multi-threaded, the FLAG is set after a thread in front, and can be reset by other threads before it is tested by the IF statement. Use the volatile keyword to declare the variable, you can tell the compiler When compiling, you do not need to optimize this part of the code by predicting the variable value.

Unable to access threads sometimes do not have problems with object locks, threads still have possible access to blocking states. IO is the best example of this type of problem in Java programming. This object should still be accessed by other threads when blocking IO calls within the object. This object is usually responsible for canceling this blocking IO operation. Threads that cause the blocking call often fail to fail the synchronization task. If other methods of the object are also synchronized, this object is equivalent to being frozen when the thread is blocked. Other threads cannot send messages (for example, cancel IO operations) because they cannot get locks of the object. It is important to ensure that those blocking calls are not included in the sync code, or confirmed that there is a non-synchronization method in an object with synchronous blocking code. Although this method takes some attention to ensure the results code safely, it allows the object to be able to respond to other threads after blocking the object's thread. Call Yield () method The current thread can be removed from the processor into the ready-to-read queue. Another method is to call the SLEEP () method, allowing the thread to abandon the processor, and sleep within the time interval specified in the SLEEP method. As you think, these methods will be placed in place in the code and cannot guarantee normal work. If the thread is having a lock (because it is in a synchronization method or code block), this lock cannot be released when it calls yield (). This means that even if this thread has been hang, wait for this lock release from other threads that still can't continue to run. In order to alleviate this problem, it is best not to call the Yield method in the synchronous method. Packing those that need to be synchronized in a synchronization block, there is no non-synchronous method, and Yield is called outside of these synchronization code blocks. Another solution is to call the wait () method, allow the processor to abandon the lock it currently owns. This method can work well if the object is synchronized at the method level. Because it only uses a lock. Wait () will not be abandoned if it uses a Fine-Grained lock. In addition, a thread that blocks the wait () method, only when other threads call notifyAll (). When multi-threaded programming, synchronous mutual exclusive mechanisms are often used, but Java itself does not provide synchronous mutex, only two methods related to synchronous mutual exclusion: Wait () and notify (), can be used Design Signal Class: MySemaphore, it is designed in the ideological design of counting semaphors as proposed in Dijkstra. MySemaphore has two most important members: P () and v (). These two methods actually realize the P operation and V operation of the semaphore. Described as follows: public synchronized void P () {semaphore--; if (semaphore <0) {try {wait ();} catch (InterruptedException ie) {}}} public synchronized void V () {semaphore ; if (semaphore <= 0) NOTIFY ();} where the Semaphore variable records the state of the semaphore, the wait () method is equivalent to the block primitive, used to block the execution of the thread, the notify () method is equivalent to Wakeup primitives for waking up Thread recovery run. Since these two methods are defined as synchronized, the Java virtual machine ensures that the atoms of the two methods are implemented, thereby implementing P, V operation. Second, the communication between multiple threads of the pipeline concurrent program is usually made using the pipeline, and the JDK provides two pipe classes: PipedInpustream and PipedputStream, for input, the latter used to output.

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

New Post(0)