zoukankan      html  css  js  c++  java
  • 并发资源共享处理方案--初级

    • 锁机制实现:一般是最容易想到的方式,可以基于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 选择适合自己的方式

  • 相关阅读:
    json_encode([0])
    try catch throw
    如何 lookback
    协程||进程
    客户错了?
    循环 php 变量会影响到传入的参数
    csv变成xls, csv乱码
    虚拟机不能git push
    数组下标大小写
    php 静态方法
  • 原文地址:https://www.cnblogs.com/frinder6/p/5531212.html
Copyright © 2011-2022 走看看