1. 程式人生 > >寫一個執行緒安全的投票系統

寫一個執行緒安全的投票系統

有一個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"));


    }
}