并发控制的一个实现

在项目中,我们的数据以位图的形式存放于Redis当中,一般一份数据在2M左右。每天做任务的时候会有大量的数据读写操作,产生较大的流量,导致带宽占用很高。所以,需要对读写进行并发的控制。下面是我的并发控制的实现(因为已经够用,所以就没有再考虑公平性、性能等问题)。


并发控制器:

package com.bin.ccrc;

import java.util.concurrent.atomic.AtomicInteger;

/**
 * 并发控制器
 */
public class CcrControl {

	private volatile AtomicInteger curCcr = new AtomicInteger(0);
	private volatile Object lock = new Object();

	/**
	 * 执行指定任务,并做并发控制
	 * @param task
	 * @return
	 */
	public  T runTask(CcrTask task) {
		try {
			// 检查是否可执行,不可执行则等待
			synchronized (lock) {
				while (curCcr.get() >= task.maxCcr()) {
					try {
						lock.wait();
					} catch (InterruptedException e) {
						// Exception handling
					}
				}
				curCcr.incrementAndGet();
			}
			// 执行操作
			return task.exec();
		} catch (Exception e) {
			// Exception handling
		} finally {
			// 释放并发数,唤醒等待线程
			synchronized (lock) {
				curCcr.decrementAndGet();
				lock.notifyAll();
			}
		}
		return null;
	}
}


抽象任务:

package com.bin.ccrc;

/**
 * 抽象任务
 */
public interface CcrTask {
	/**
	 * 实际执行的操作
	 * @return
	 */
	public T exec();

	/**
	 * 允许的最大并发数
	 * @return
	 */
	public int maxCcr();
}
  

具体任务: 

package com.bin.ccrc;


/** 
 *具体任务 
 */
public class ActualTask implements CcrTask {

	@Override
	public Integer exec() {
		// 执行任务
		try {
			// 模拟任务执行
			System.out.println(Thread.currentThread().getName() + " is runing...");
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		return 1;
	}

	@Override
	public int maxCcr() {
		return 2;
	}

}
  

任务测试:

package com.bin.ccrc;


/** 
 * Test 
 */
public class TaskTest {

	private volatile static CcrControl ccrControlInstance;

	private static CcrControl getCcrControlInstance() {
		if (ccrControlInstance == null) {
			synchronized (ActualTask.class) {
				if (ccrControlInstance == null) {
					ccrControlInstance = new CcrControl();
				}
			}
		}
		return ccrControlInstance;
	}

	/**
	 * run task
	 * @return
	 */
	public static int runTask() {
		ActualTask task = new ActualTask();
		int rs = getCcrControlInstance().runTask(task);

		return rs;
	}

	public static void main(String[] args) {
		for (int i = 0; i < 10000; i++) {
			new Thread(new Runnable() {

				@Override
				public void run() {
					TaskTest.runTask();
				}
			}, "t-" + i).start();
			;
		}
	}
}
  




你可能感兴趣的:(Java)