同期と同時demo:スループットの増加

5958 ワード

package test.lock;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class TestConcurrent {
	private static final int LOCK_SIZE = 10;
	private static final Lock[] locks = new ReentrantLock[10];
	private static final Map<String, List<String>> dataMap ;
	static {
		dataMap = new ConcurrentHashMap<String, List<String>>();
		for (int i = 0; i < LOCK_SIZE; i++) {
			locks[i] = new ReentrantLock();
		}
	}

	public int count(String userid) {
		final Lock lock = locks[userid.hashCode() & (LOCK_SIZE - 1)];
		lock.lock();
		try {
			List<String> list = null;
			list = dataMap.get(userid);
			if (list != null) {
				System.out.println(Thread.currentThread().getName()
						+ ",userid:" + userid + ",get from cache");
			} else {
				System.out.println(Thread.currentThread().getName()
						+ ",userid:" + userid + ",get from db");
				list = loadData(userid);
				dataMap.put(userid, list);
			}
			return list != null ? list.size() : 0;
		} finally {
			lock.unlock();
		}
	}

	private List<String> loadData(String userid) {
		//  
		// sleep 1s
		sleeper(1000);
		Random r = new Random();
		List<String> list = new ArrayList<String>();
		int size = r.nextInt(1000);
		for (int i = 0; i < size; i++) {
			list.add(i + "");
		}
		return list;
	}

	private void sleeper(int time) {
		try {
			Thread.sleep(time);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	public static void main(String[] args) {
		final TestConcurrent t = new TestConcurrent();
		ExecutorService executor = Executors.newCachedThreadPool();
		executor.submit(new Task(t, new String(20 + "")));
		executor.submit(new Task(t, new String(20 + "")));
		executor.submit(new Task(t, new String(20 + "")));
		executor.submit(new Task(t, new String(20 + "")));
		executor.submit(new Task(t, new String(20 + "")));
		executor.submit(new Task(t, new String(20 + "")));
		executor.submit(new Task(t, new String(88 + "")));
		executor.submit(new Task(t, new String(88 + "")));
		executor.submit(new Task(t, new String(88 + "")));
		executor.submit(new Task(t, new String(88 + "")));
		executor.submit(new Task(t, new String(88 + "")));
		executor.submit(new Task(t, new String(88 + "")));
		executor.submit(new Task(t, new String(99 + "")));
		executor.submit(new Task(t, new String(88 + "")));
		executor.submit(new Task(t, new String(55 + "")));
		executor.submit(new Task(t, new String(22 + "")));
		executor.submit(new Task(t, new String(44 + "")));
		executor.submit(new Task(t, new String(11 + "")));
		executor.submit(new Task(t, new String(44 + "")));
		executor.submit(new Task(t, new String(57 + "")));
		executor.submit(new Task(t, new String(78 + "")));
		executor.submit(new Task(t, new String(54 + "")));
		executor.submit(new Task(t, new String(123 + "")));
		executor.submit(new Task(t, new String(452 + "")));
		executor.submit(new Task(t, new String(88 + "")));
		executor.submit(new Task(t, new String(88 + "")));
		executor.submit(new Task(t, new String(88 + "")));
		executor.submit(new Task(t, new String(88 + "")));
		executor.submit(new Task(t, new String(88 + "")));
	}

	private static class Task implements Runnable {
		private TestConcurrent t;
		private String userid;

		public Task(TestConcurrent t, String userid) {
			this.t = t;
			this.userid = userid;
		}

		@Override
		public void run() {
			int result = t.count(userid);
			// TODO
		}
	}
}

 
 :
pool-1-thread-1,userid:20,get from db
pool-1-thread-8,userid:88,get from db
pool-1-thread-24,userid:452,get from db
pool-1-thread-22,userid:54,get from db
pool-1-thread-3,userid:20,get from cache
pool-1-thread-10,userid:88,get from cache
pool-1-thread-2,userid:20,get from cache
pool-1-thread-12,userid:88,get from cache
pool-1-thread-6,userid:20,get from cache
pool-1-thread-5,userid:20,get from cache
pool-1-thread-14,userid:88,get from cache
pool-1-thread-4,userid:20,get from cache
pool-1-thread-16,userid:22,get from db
pool-1-thread-21,userid:78,get from db
pool-1-thread-18,userid:11,get from db
pool-1-thread-7,userid:88,get from cache
pool-1-thread-20,userid:57,get from db
pool-1-thread-9,userid:88,get from cache
pool-1-thread-11,userid:88,get from cache
pool-1-thread-13,userid:99,get from db
pool-1-thread-26,userid:88,get from cache
pool-1-thread-15,userid:55,get from db
pool-1-thread-28,userid:88,get from cache
pool-1-thread-17,userid:44,get from db
pool-1-thread-19,userid:44,get from cache
pool-1-thread-23,userid:123,get from db
pool-1-thread-27,userid:88,get from cache
pool-1-thread-25,userid:88,get from cache
pool-1-thread-29,userid:88,get from cache