控制线程数量之-Semaphore

[b]使用Semaphore的简单例子了解一下Semaphore使用[/b]
//这里可能是在一个项目中唯一使用的一个newCachedThreadPool,别的都是new一个fixed的大小
public static ExecutorService exec = Executors.newCachedThreadPool();
private static List<String> userList;

static {
userList=new ArrayList<String>();
for (int i = 0; i < 100; i++){
userList.add(String.valueOf(i));
}
}


/**
* 使用信号量控制线程数量
*/
public static void simpleSemaphore() {
//构建最大的线程并发
final Semaphore sem = new Semaphore(10);

final Semaphore sycSem = new Semaphore(5, true);//这里使用非竞争锁
//模拟100个客户访问
for (final String user:userList) {
Runnable run = new Runnable() {
public void run() {
try {
sem.acquire();//获得允许
System.out.println(user + "用户进入----");
sem.release();//释放访问
System.out.println("访问后还有" + sem.availablePermits() + "个线程空间可以使用");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
exec.execute(run);
}
exec.shutdown();
}

执行结果
0用户进入----
访问后还有10个线程空间可以使用
1用户进入----
访问后还有9个线程空间可以使用
16用户进入----
访问后还有9个线程空间可以使用
6用户进入----
访问后还有9个线程空间可以使用
19用户进入----
访问后还有9个线程空间可以使用
23用户进入----
访问后还有9个线程空间可以使用
26用户进入----


[b]如果把上边的用户换成一个个线程池该怎么处理[/b]
 //这里可能是在一个项目中唯一使用的一个newCachedThreadPool,别的都是new一个fixed的大小
public static ExecutorService exec = Executors.newCachedThreadPool();

private static BlockingQueue<TaskPool> taskPools = new ArrayBlockingQueue<TaskPool>(1000);


private String user;

public static void addPoolTask(TaskPool user) {
if (taskPools.size() < 1000) {//建议添加初始化值
taskPools.add(user);
} else {
//转移或者是做别的处理
}
}

/**
* 使用信号量控制线程数量
*/
public static void simpleSemaphore() {
//构建最大的线程并发
final Semaphore sem = new Semaphore(10);

final Semaphore sycSem = new Semaphore(5, true);//这里使用非竞争锁
//模拟100个客户访问
while (taskPools.size() > 0) {
try {
final TaskPool taskPool = taskPools.take();
Runnable run = new Runnable() {
public void run() {
try {
sem.acquire();//获得允许
//这里执行对应的task池事情
taskPool.excute();

sem.release();//释放访问
System.out.println("线程池" + taskPool.toString() + "访问后还有" + sem.availablePermits() + "个线程空间可以使用");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
exec.execute(run);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
exec.shutdown();
}

基于用户扩展的多线程池管理


public interface TaskPool {

void excute();
}
public class MyFirstPoolTask implements TaskPool {

public ExecutorService exec = Executors.newFixedThreadPool(1);
private int init;
private int max = 10;

public MyFirstPoolTask(int init) {
if (max < init)
System.out.println("数值过大");
this.exec = Executors.newFixedThreadPool(init);
}


public void excute() {
for (int i = 0; i < 5; i++) {
final int z = i;
Runnable rn = new Runnable() {
public void run() {
System.out.println("MyFirstPoolTask进行我的业务处理"+Thread.currentThread().getName());
}
};
exec.execute(rn);
}
exec.shutdown();
}
}

public class MySecondPoolTask implements TaskPool {

public ExecutorService exec = Executors.newFixedThreadPool(1);
private int init;
private int max = 10;

public MySecondPoolTask(int init) {
if (max < init)
System.out.println("数值过大");
this.exec = Executors.newFixedThreadPool(init);
}


public void excute() {
for (int i = 0; i < 5; i++) {
final int z = i;
Runnable rn = new Runnable() {
public void run() {
System.out.println("MySecondPoolTask进行我的业务处理"+Thread.currentThread().getName());
}
};
exec.execute(rn);
}
exec.shutdown();
}
}


执行后的结果
线程池test.com.jd.hotel.janleTest.MyFirstPoolTask@2678a212访问后还有9个线程空间可以使用
MyFirstPoolTask进行我的业务处理pool-3-thread-3
MyFirstPoolTask进行我的业务处理pool-3-thread-3
MyFirstPoolTask进行我的业务处理pool-3-thread-3
线程池test.com.jd.hotel.janleTest.MySecondPoolTask@151a64ed访问后还有10个线程空间可以使用
MySecondPoolTask进行我的业务处理pool-5-thread-1
MySecondPoolTask进行我的业务处理pool-5-thread-1
MyFirstPoolTask进行我的业务处理pool-3-thread-1
MySecondPoolTask进行我的业务处理pool-5-thread-4
MySecondPoolTask进行我的业务处理pool-5-thread-2
MyFirstPoolTask进行我的业务处理pool-3-thread-2
MySecondPoolTask进行我的业务处理pool-5-thread-3
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值