1.解決方法
Executors.newSingleThreadExecutor()取得的Executor實例有以下特性:
任務順序執行. 比如:
executor.submit(task1);
executor.submit(task2);
必須等task1執行完,task2才能執行。
task1和task2會被放入一個隊列里,由一個工作線程來處理。即:一共有2個線程(主線程、處理任務的工作線程)。
任務順序執行. 比如:
executor.submit(task1);
executor.submit(task2);
必須等task1執行完,task2才能執行。
task1和task2會被放入一個隊列里,由一個工作線程來處理。即:一共有2個線程(主線程、處理任務的工作線程)。
以上如果是單機可以解決,如果是多台服務器的話,仍然還是會存在並發的問題.
或者使用mysql數據庫修改的特性,update排序依次來修改,增加否決字段,修改的時候帶上條件值,可以解決並發問題.(多個租客租時間段重疊的同一輛車且自動接單,這個情況就很明顯凸現出來.)
2.測試代碼
/** * */ package mock; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Semaphore; import com.autoyolConsole.util.esb.HttpUtils; /** * @author xxx * @function * @date 2016年3月15日 * @version 1.0 */ public class ConcurrentTest2 { private static int thread_num = 5; private static int client_num = 20; private static final String reqUrl = "http://10.0.3.213:7064/"; private static String url = "tranxx/vxx/reqx"; private static String[] tokens = new String[]{"4dafe25e1f8f4e368834f95b75030193","6a3d3702cccf46a3b94e2c805a16c0a3","a4ee5ad888714a9e9d0d4646e725495b","9adbecae26f648dea2767e8d908463dd","20910b477f0142f6b7f709babcdafb72", "c3c53c987256422a8667a455a1cd1117","efb1f941eab440619d8a339f2fafa429","786a901fe5414d14894ca4db738efe2f","8fbad92b9a7c4d4b8a420db23c405e49","75992aa62eb947739f0bfc8a83234584", "aa110a58ade241a3b456b8be5ddd2551","aa110a58ade241a3b456b8be5ddd255a","aa110a58ade241a3b456b8be5ddd2552","aa110a58ade241a3b456b8be5ddd2553","aa110a58ade241a3b456b8be5ddd2554", "aa110a58ade241a3b456b8be5ddd2555","aa110a58ade241a3b456b8be5ddd2556","aa110a58ade241a3b456b8be5ddd2557","aa110a58ade241a3b456b8be5ddd2558","aa110a58ade241a3b456b8be5ddd2559"}; private static String[] mobiles = new String[]{"197xxxx9705","199xxxx5297","199xxxx8606","198xxxx9898","197xxxx1330", "197xxxx9999","193xxxx2233","193xxxx2345","191xxxx6712","198xxxx6852", "191xxxx6820","987xxxx0296","190xxxx7589","199xxxx8888","193xxxx2312", "199xxxx5496","161xxxx3280","190xxxx1082","199xxxx3724","199xxxx0537"}; public static void main(String[] args) { ExecutorService exec = Executors.newCachedThreadPool(); // thread_num個線程可以同時訪問 final Semaphore semp = new Semaphore(thread_num); // 模擬client_num個客戶端訪問 for (int index = 0; index < client_num; index++) { final int NO = index; Runnable run = new Runnable() { public void run() { try { // 獲取許可 semp.acquire(); System.out.println("Thread並發事情>>>"+ NO); String strReq = "{\"carNo\":\"303473636\",\"token\":\""+tokens[NO]+"\",\"conPhone\":\""+mobiles[NO]+"\"," + "\"rentTime\":\"20160519183000\",\"revertTime\":\"20160522183000\",\"rentReason\":\"上下班用車\",\"oilType\":\"1\",\"disCouponIds\":\"0\",\"useBal\":\"0\",\"source\":\"3\",\"rentCity\":\"本市\"}"; try { String result = HttpUtils.appPost(strReq, reqUrl+ url); System.err.println("接口調用返回結果:" + result); } catch (Exception e) { e.printStackTrace(); } semp.release(); } catch (Exception e) { e.printStackTrace(); } } }; exec.execute(run); } // 退出線程池 exec.shutdown(); } }