有一個map,key存儲候選人名稱,value存儲該候選人的得票數。請實現一個線程安全的投票系統.java
爲了測試併發環境下的表現,咱們先設計一個小的「框架」,用來模擬併發狀況下的投票行爲。 首先設計一個接口,代測試的代碼在這個接口的方法裏面被調用安全
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")); } }