有一个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 HashMapresult = new HashMap(3); private static ConcurrentHashMap 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")); }}