併發資源共享處理方案--初級

  • 鎖機制實現:通常是最容易想到的方式,能夠基於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/1741871java

 

 

能夠參考:http://my.oschina.net/leoson/blog/107327 選擇適合本身的方式apache

相關文章
相關標籤/搜索