并发资源共享处理方案--初级
- 锁机制实现:一般是最容易想到的方式,可以基于synchronized关键字,使用同步方法(大粒度)或同步代码块(小粒度),也可以使用Lock方式,更灵活的实现;
package com.share; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import org.apache.log4j.Logger; /** * * @ClassName: LockShare * @Description: TODO(使用锁机制实现资源共享) * @date 2016年5月26日 下午2:51:16 * */ public class LockShare implements Runnable { private static Logger logger = Logger.getLogger(LockShare.class); private ThreadLocal<Integer> saleCount = new ThreadLocal<Integer>(); // 锁 private Lock lock = new ReentrantLock(); private int tickets; private boolean isOver = false; public LockShare(int tickets) { super(); this.tickets = tickets; } @Override public void run() { long beginTime = System.currentTimeMillis(); while (!isOver) { // syncBlockSale(); // syncMethodSale(); lockSale(); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } long endTime = System.currentTimeMillis(); logger.info(Thread.currentThread().getName() + " : " + (endTime - beginTime)); } /** * * @Title: lockSale * @Description: TODO(使用锁实现资源共享) * @return void * @date 2016年5月25日 下午4:58:18 * @throws */ private void lockSale() { lock.lock(); try { sale(); } finally { lock.unlock(); } } /** * * @Title: syncMethodSale * @Description: TODO(同步方法实现资源共享) * @return void * @date 2016年5月25日 下午4:49:45 * @throws */ private synchronized void syncMethodSale() { sale(); } /** * * @Title: synchronizedSale * @Description: TODO(同步代码块实现资源共享) * @return void * @date 2016年5月25日 下午4:46:46 * @throws */ private void syncBlockSale() { synchronized (this) { sale(); } } private void sale() { if (tickets > 0) { tickets--; int beforeCount = getBeforeCount(); saleCount.set(++beforeCount); logger.debug(Thread.currentThread().getName() + " : " + saleCount.get()); } else { isOver = true; } } private int getBeforeCount() { Integer beforeCount = saleCount.get(); if (null == beforeCount) { logger.info("init ThreadLocal..."); saleCount.set(0); beforeCount = saleCount.get(); } return beforeCount; } public static void main(String[] args) { int tickets = 100; LockShare share = new LockShare(tickets); for (int i = 0; i < 3; i++) { new Thread(share).start(); } } }
- 使用Concurrent包中的工具类实现,这里使用的是AtomicInteger
package com.share; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; import org.apache.log4j.Logger; import com.alibaba.fastjson.JSON; /** * * @ClassName: ConcurrentShare * @Description: TODO(使用AtomicInteger实现多线程资源共享) * @date 2016年5月26日 下午2:50:21 * */ public class ConcurrentShare implements Runnable { private static Logger logger = Logger.getLogger(ConcurrentShare.class); private ThreadLocal<Map<String, List<Integer>>> saleTickets = new ThreadLocal<Map<String, List<Integer>>>(); /** * 使用atomic保证资源共享 */ private AtomicInteger tickets; private boolean isOver = false; public ConcurrentShare(AtomicInteger tickets) { super(); this.tickets = tickets; } @Override public void run() { while (!isOver) { sale(); } logger.info(JSON.toJSONString(saleTickets.get())); logger.info(saleTickets.get().get(Thread.currentThread().getName()).size()); } /** * * @Title: sale * @Description: TODO(售卖方法) * @return void * @date 2016年5月26日 上午9:50:10 * @throws */ private void sale() { if (tickets.get() > 0) { int t = tickets.decrementAndGet(); getBeforeTickts().get(Thread.currentThread().getName()).add(t); } else { isOver = true; } } private Map<String, List<Integer>> getBeforeTickts() { Map<String, List<Integer>> beforeTickets = saleTickets.get(); if (null == beforeTickets) { Map<String, List<Integer>> map = new HashMap<String, List<Integer>>(); map.put(Thread.currentThread().getName(), new ArrayList<Integer>()); saleTickets.set(map); beforeTickets = saleTickets.get(); } return beforeTickets; } public static void main(String[] args) { AtomicInteger tickets = new AtomicInteger(100); ConcurrentShare share = new ConcurrentShare(tickets); for (int i = 0; i < 3; i++) { new Thread(share).start(); } } }
AtomicInteger的实现原理,可以参见:http://aswang.iteye.com/blog/1741871
可以参考:http://my.oschina.net/leoson/blog/107327 选择适合自己的方式