并发资源共享处理方案--初级

  • 锁机制实现:一般是最容易想到的方式,可以基于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();
        }
    }

}
View Code

 

  • 使用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();
        }
    }

}
View Code

  AtomicInteger的实现原理,可以参见:http://aswang.iteye.com/blog/1741871

 

 

可以参考:http://my.oschina.net/leoson/blog/107327 选择适合自己的方式

 

posted @ 2016-05-26 15:08  每天一点  阅读(276)  评论(0编辑  收藏  举报