For concurrent programming, we think of the critical resource competition that is always equal to multithreading. However, you will often encounter the following scenario:
A daemon thread provides a critical resource, and multiple child threads can concurrently overwrite that critical resource. Most of the time (99.9% of a day), the main thread is not interfering with the competition between the threads, usually as long as the critical resource itself is internally processed to synchronize. But occasionally the main thread will intervene in this critical resource, such as doing some statistics, making a snapshot, or copying the data and then emptying it. This typically takes a long time, and you do not want someone to overwrite critical resources during this time. If the main thread uses the same lock or synchronized synchronization as each sub-thread, then there is no need for the blocking to open up when the main thread is not doing so, and the sub-threads are blocked by the competition.
This article describes a feature that uses volatile variables to solve this problem. Try to achieve the maximum balance between performance and data protection. The atomic variable is implemented using a register variable. The current state of the map table is marked with two variables. Instead of locking or synchronizing between a background thread and many business threads, the performance of volatile variables is better than locks in most cases (Java theory and Practice: using volatile variables correctly). This is only an example of a map table, and other data structures that ensure thread safety are also available.
Imagine the introduction of a lock or synchronized between the Addonerecord method and the Getandclearallrecords method, so that every two business threads compete when adding data, and this competition is unnecessary. Because, this lock is meaningful only if the background thread calls Getandclearallrecords. The introduction of two register variables can effectively reduce the problem of some lock competition. Of course, here just take Concurrenthashmap to give an example, perhaps in the Dosomethingwithmap method there is no need to monopolize the entire map table, then the entire synchronization mechanism is not required, as long as the map table itself synchronization.
/*** The thread used to flag the long-running exclusive table is working. */ PrivateAtomicboolean closed =NewAtomicboolean (false); /*** Used to flag whether the current data table is inserting data. */ PrivateAtomicinteger busy =NewAtomicinteger (); /*** A table for storing data. */ Privateconcurrenthashmap<string, string> map =NewConcurrenthashmap<string, string>();
/*** Multiple threads will call this interface concurrently to insert data into the * map table. * @paramKey *@paramvalue*/ Public voidAddonerecord (string key, String value) {/*** Most of the time, this cycle does not consume performance resources. */ while(Closed.get ()) {waitamoment (); } if(Map! =NULL) { /*** Use a synchronization variable to count on each thread. */busy.getandincrement (); Map.put (key, value); Busy.getanddecrement (); } } /*** The background thread processes the data in the map table on a regular basis. */ Public voidgetandclearallrecords () {synchronized( This) { /*** First set the closed flag so that the map table is exclusive; * Avoid being modified during the operation. */Closed.set (true); while(Busy.get ()! = 0) {waitamoment (); } dosomethingwithmap (map); Closed.set (false); } } Private voidDosomethingwithmap (concurrenthashmap<string, string>map) { //TODO auto-generated Method Stub } Private voidwaitamoment () {//TODO auto-generated Method Stub }
Always feel that the analysis of this problem a bit tangled feeling, in fact, with Java, this performance loss can be negligible. And the outer two register variable reading and writing is not necessarily better than the lock performance, and in the case of external lock, the map table itself lock competition does not exist, and actually only 1 locks in effect, it seems that the problem is not so bad. In any case, this job feeling has some meaning, it is always better than the pros and cons.
The processing of a common concurrent programming scenario