寫一個執行緒安全的投票系統
阿新 • • 發佈:2019-05-20
有一個map,key儲存候選人名稱,value儲存該候選人的得票數。請實現一個執行緒安全的投票系統.
為了測試併發環境下的表現,我們先設計一個小的“框架”,用來模擬併發情況下的投票行為。 首先設計一個介面,代測試的程式碼在這個介面的方法裡面被呼叫
public interface Worker {
void doWork();
}
然後是併發執行器
public class ConcurrentRunner { private static int threadCount = 0; private Worker worker; public void setWorker(Worker w){ worker = w; } private ExecutorService service = Executors.newCachedThreadPool(); ConcurrentRunner(int count ){ threadCount = count; } private final CountDownLatch countDownLatch = new CountDownLatch(threadCount); public void run(){ for (int i = 0; i < threadCount; i++) { Runnable runnable = new Runnable() { public void run() { try { countDownLatch.await(); worker.doWork(); } catch (Exception e) { e.printStackTrace(); } } }; service.execute(runnable); //達到threadcount執行緒數量的時候,所有執行緒以前執行 countDownLatch.countDown(); } } }
下面進入正題,這個題目主要考察的是併發控制,當然你可以用整個方法都加鎖來實現,但是效率低下,借鑑CAS的思想來實現是最優解決方案:
import java.util.HashMap;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
/**
* Created by yzy on 2018/10/31.
*/
public class Main {
/**
* 投票人數量
*/
public static final int VOTER_COUNT = 100;
/**
* 候選人數量
*/
public static final int CANDINATE_COUNT = 3;
/**
* 候選人
* @param args
*/
public static final String[] candinator = {"tom","lily","jimmy"} ;
// private static HashMap<String , Integer> result = new HashMap(3);
private static ConcurrentHashMap<String , Integer> result = new ConcurrentHashMap(3);
public static void main(String[] args) {
ConcurrentRunner concurrentRunner = new ConcurrentRunner(VOTER_COUNT);
concurrentRunner.setWorker(new Worker() {
@Override
public void doWork() {
Random random = new Random();
int index = random.nextInt(3);
System.out.println("who="+index);
String who = candinator[index];
// int num = result.get(who);
// result.put(who,1);
result.putIfAbsent(who,0);
int num = 0;
// while(!result.replace(who,num=result.get(who),num++)){
// while(!result.replace(who,num=result.get(who),++num)){
while(!result.replace(who,num=result.get(who),num + 1)){
}
}
});
concurrentRunner.run();
System.out.println("tom 票數" + result.get("tom"));
System.out.println("lily 票數 " + result.get("lily"));
System.out.println("jimmy 票數" + result.get("jimmy"));
}
}