Make Alipay payment access when encountering a problem on the same order, there may be a "Alipay server asynchronous Notification payment result update status" and "User initiative request to initiate query payment result update status" two procedures. Because a transaction request is made to another system after the query wants the user to pay the order, two process threads must be synchronized at update time for the same order. However, if you do not differentiate the entire Update method lock, then the concurrent amount is not going to go. Comprehensive consideration, I decided to implement a locking mechanism, requiring the Update method after the lock to do the following requirements: 1, for different orders, the thread that executes the Update method is executed asynchronously; 2. The thread that executes the Update method is executed synchronously on the same order.
The initial code implementation is as follows:
Import Java.util.HashMap; /** * Order lock, when two threads simultaneously operate the same Oderno order, enter critical section, different Oderno does not involve critical zone operation .<br> * <p>long order=1234l;<br> * try{< br> * Orderlock.lock (oderno);<br> * Sync Code Execution ......<br> *}finally{<br> * orderlock.unlock (); <BR&G
T *}</p> * <br> */public class Orderlock {private final static hashmap<long,objectlocker<string
>> lockerstore=new hashmap<long,objectlocker<string>> ();
Private final Static Object Lock=new object (); /** * Try to enter the order number critical section, the other line Chengjo after calling this order number into, then wait for this thread to release the lock before entering the critical section * @param oderno order number, if there are other threads using the same order number call this method,
You need to wait for other threads to call the Unlock method before entering the critical section/public static void Lock (String oderno) {objectlocker<string> objloc=null; Synchronized (lock) {for (Long Id:LockerStore.keySet ()) {if (Lockerstore.get (ID). Equals (Oderno)) {Objloc=lock
Erstore.get (ID);
} if (objloc==null) {objloc=new objectlocker<string> (Oderno); } lockerstore.put (Thread.currentthRead (). GetId (), objloc);
} objloc.lock ();
/** * unlock, allow other threads to enter the order critical area * * public static void Unlock () {objectlocker<string> objloc=null;
Synchronized (lock) {Objloc=lockerstore.remove (Thread.CurrentThread (). GetId ());
} if (Objloc!=null) {objloc.unlock (); }/** * Object lock * * @param <T>/Static class Objectlocker<t> {Private final object locker = N
EW Object ();
Private final static Long nullthread =-1;
Private long threadId = Nullthread;
private int requestcount=0;
Private T target;
Public Objectlocker (T target) {super ();
This.target = target;
@Override public boolean equals (Object obj) {if (target==null) {return super.equals (obj);
}else{return target.equals (obj);
} public void Lock () {synchronized (locker) {requestcount++;
Do {long Currthread=thread.currentthread (). GetId (); if (Currthread = = ThreadId | | threadId = = nullthread) {threadId = Currthread;
Break
try {locker.wait ();
catch (Interruptedexception e) {e.printstacktrace ();
}} while (true);
} public void Unlock () {synchronized (locker) {requestcount--;
if (Thread.CurrentThread (). GetId () = = threadId) {threadId = Nullthread;
Locker.notifyall ();
}} public int getreqeustcount () {return requestcount;
}
}
}
Preliminary test Code
Import java.util.ArrayList;
Import Java.util.HashMap;
public class Locktest {static hashmap<long,arraylist<long>> cache=new hashmap<long,arraylist<long&
Gt;> ();
Static class Testthread extends thread{Long orderNo;
Public Testthread (Long orderNo) {super ();
This.orderno = OrderNo;
@Override public void Run () {try {sleep (2000l);
catch (Interruptedexception e) {e.printstacktrace ();
for (int i=0;i<60;++i) {try{//System.out.println ("Thread" +getid () + "Wait for lock" +orderno+ "...");
Orderlock.lock (Orderno.tostring ());
Cache.get (OrderNo). Add (GetId ());
try {sleep (20l);
catch (Interruptedexception e) {}//System.out.println ("Thread" +getid () + "Get lock" +orderno+ "...");
} finally{Cache.get (OrderNo). Add (GetId ());
Orderlock.unlock ();
}//System.out.println ("Thread" +getid () + "release lock" +orderno+ "...");
try {sleep (20l);
catch (Interruptedexception e) {e.printstacktrace (); public static void Main (S)}}}Tring[] args) {long time0=system.currenttimemillis ();
Testthread[] Ts=new testthread[24];
Cache.put (0l, New arraylist<long> ());
Cache.put (1l, New arraylist<long> ());
Cache.put (2l, New arraylist<long> ());
Cache.put (3l, New arraylist<long> ());
for (int i=0;i<ts.length;++i) {ts[i]=new testthread (i%4l);
Ts[i].start ();
for (int i=0;i<ts.length;++i) {try {ts[i].join ();
The catch (Interruptedexception e) {}} System.out.println (System.currenttimemillis ()-TIME0);
For (Long Key:cache.keySet ()) {arraylist<long> l=cache.get (key);
int len=l.size ()/2;
for (int i=0;i<len;i++) {if (!l.get (2*i). Equals (L.get (2*i+1))) {System.out.println (2*i);
System.out.println (L.get (2*i));
System.out.println (L.get (2*i+1));
System.out.println (List2string (l));
throw new RuntimeException ("error occurred");
}//System.out.println (List2string (l));
} static String list2string (arraylist<long> l) { String tmp= "";
for (Long i:l) {tmp+=i+ ",";
return TMP; }
}