題目:設計多線程統計器。啓動N個線程,線程執行時,打印每一個線程執行的次數,和全部線程執行次數和java
不對的地方,或者更好的,望指點。多線程
package lcr; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ThreadFactory; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.locks.ReentrantLock; import com.google.common.util.concurrent.AtomicLongMap; public class MultiThreadCounter { private static MultiThreadCounter pvs = null; private static ScheduledExecutorService service = null; private static ReentrantLock lock = new ReentrantLock(); private static AtomicLongMap<String> pvCounterMap = AtomicLongMap.create(); private static int MONITOR_INITIAL_DELAY_SECONDS = 3; // 監控初始延遲秒數 private static int MONITOR_INTERVAL_SECONDS = 10; // 監控間隔秒數 private static Map<String, Long> map2 = new HashMap<String, Long>(); private static AtomicInteger atomic = new AtomicInteger(0); public long lncr(String key) { long result = -1; while (true) { if (!lock.isLocked()) { result = pvCounterMap.incrementAndGet(key); atomic.incrementAndGet(); break; } else { try { TimeUnit.MILLISECONDS.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } } } return result; } public MultiThreadCounter() { createExecutorService(); startMonitor(); } public static MultiThreadCounter newInstance() { if (pvs == null) { synchronized (MultiThreadCounter.class) { if (pvs == null) { pvs = new MultiThreadCounter(); } } } return pvs; } private void startMonitor() { service.scheduleWithFixedDelay(new StatMonitorRunner(), MONITOR_INITIAL_DELAY_SECONDS, MONITOR_INTERVAL_SECONDS, TimeUnit.SECONDS); } private void createExecutorService() { if (service == null) { service = Executors.newScheduledThreadPool(1, new ThreadFactory() { @Override public Thread newThread(Runnable r) { Thread thread = new Thread(r); thread.setDaemon(true); // 宿主線程 return thread; } }); } } private Map<String, Long> popCounter() { Map<String, Long> newMap = new HashMap<String, Long>(); lock.lock(); try { for (Iterator<String> it = pvCounterMap.asMap().keySet().iterator(); it.hasNext();) { String key = it.next(); newMap.put(key, pvCounterMap.get(key)); } pvCounterMap.clear(); } finally{ lock.unlock(); } return newMap; } class StatMonitorRunner implements Runnable { @Override public void run() { Map<String, Long> map = popCounter(); for(Iterator<String> it = map.keySet().iterator(); it.hasNext(); ){ String key = it.next(); if(map2.containsKey(key)) { map2.put(key, new Long(map2.get(key).longValue()+map.get(key).longValue())); }else { map2.put(key, map.get(key)); } } System.out.println("結果:"+map2); System.out.println("總計數:"+atomic.get()); } } }
package lcr; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; public class CounterTest { public static void main(String[] args) { ScheduledExecutorService service = Executors.newScheduledThreadPool(6); for (int i = 0; i < 6; i++) { CounterTest t = new CounterTest(); String name = "name"+i; service.scheduleWithFixedDelay(t.new MyRunner(name), 0, 1000, TimeUnit.MILLISECONDS); } } class MyRunner implements Runnable{ private String name; public MyRunner(String name) { this.name = name; } @Override public void run() { long l = MultiThreadCounter.newInstance().lncr(this.name); //System.out.println(this.name+" > " + l); } } }