java 线程调用_java多线程之Semaphore使用

本文将介绍用来控制资源同时访问个数的Semaphore工具类,然后采用Semaphore给出一个泊车的实例,最后给出Semaphore和CountDownLatch的几点比较。

一. Semaphore工具类介绍

/**

* A counting semaphore. Conceptually, a semaphore maintains a set of

* permits. Each {@link #acquire} blocks if necessary until a permit is

* available, and then takes it. Each {@link #release} adds a permit,

* potentially releasing a blocking acquirer.

* However, no actual permit objects are used; the Semaphore just

* keeps a count of the number available and acts accordingly.

*

*

Semaphores are often used to restrict the number of threads than can

* access some (physical or logical) resource.

*/

从Semaphore的注释中可以看出如下几点:

1.从概念上讲,信号量维护了一个许可集。如有必要,在许可可用前会阻塞每一个 acquire(),然后再获取该许可。每个 release() 添加一个许可,从而可能释放一个正在阻塞的获取者。

2. Semaphore并不使用实际的许可对象,Semaphore 只对可用许可进行计数,并采取相应的行动。

3.Semaphore 通常用于限制可以访问某些资源(物理或逻辑的)的线程数目。

Semaphore中定义了一个内部类Sync,该类继承AbstractQueuedSynchronizer。从代码中可以看出,Semaphore的方法基本上都调用了Sync的方法来实现。Smaphore还提供了公平和非公平的两种方式。

Semaphore工具类相关的类图如下:

cdef81975a4bda9777efd35b75dfdcbf.png

二. Semaphore工具类的使用案例

下面给出的示例模拟30辆车去泊车,而车位有10个的场景。当车位满时,出来一辆车,才能有一辆车进入停车。

Car.java

package my.concurrent.semaphore;

import java.util.concurrent.Semaphore;

public class Car implements Runnable {

private final Semaphore parkingSlot;

private int carNo;

/**

* @param parkingSlot

* @param carName

*/

public Car(Semaphore parkingSlot, int carNo) {

this.parkingSlot = parkingSlot;

this.carNo = carNo;

}

public void run() {

try {

parkingSlot.acquire();

parking();

sleep(300);

parkingSlot.release();

leaving();

} catch (InterruptedException e) {

e.printStackTrace();

}

}

private void parking() {

System.out.println(String.format("%d号车泊车", carNo));

}

private void leaving() {

System.out.println(String.format("%d号车离开车位", carNo));

}

private static void sleep(long millis) {

try {

Thread.sleep(millis);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

ParkingCars.java

package my.concurrent.semaphore;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

import java.util.concurrent.Semaphore;

public class ParkingCars {

private static final int NUMBER_OF_CARS = 30;

private static final int NUMBER_OF_PARKING_SLOT = 10;

public static void main(String[] args) {

/*

* 采用FIFO, 设置true

*/

Semaphore parkingSlot = new Semaphore(NUMBER_OF_PARKING_SLOT, true);

ExecutorService service = Executors.newCachedThreadPool();

for (int carNo = 1; carNo <= NUMBER_OF_CARS; carNo++) {

service.execute(new Car(parkingSlot, carNo));

}

sleep(3000);

service.shutdown();

/*

* 输出还有几个可以用的资源数

*/

System.out.println(parkingSlot.availablePermits() + " 个停车位可以用!");

}

private static void sleep(long millis) {

try {

Thread.sleep(millis);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

运行结果:

4号车泊车

6号车泊车

8号车泊车

2号车泊车

10号车泊车

3号车泊车

5号车泊车

11号车泊车

1号车泊车

9号车泊车

4号车离开车位

13号车泊车

8号车离开车位

7号车泊车

2号车离开车位

15号车泊车

10号车离开车位

17号车泊车

6号车离开车位

12号车泊车

3号车离开车位

16号车泊车

14号车泊车

18号车泊车

11号车离开车位

5号车离开车位

1号车离开车位

19号车泊车

20号车泊车

9号车离开车位

13号车离开车位

21号车泊车

22号车泊车

7号车离开车位

15号车离开车位

23号车泊车

17号车离开车位

24号车泊车

12号车离开车位

25号车泊车

26号车泊车

14号车离开车位

27号车泊车

28号车泊车

16号车离开车位

20号车离开车位

29号车泊车

18号车离开车位

30号车泊车

19号车离开车位

21号车离开车位

23号车离开车位

22号车离开车位

26号车离开车位

24号车离开车位

28号车离开车位

30号车离开车位

25号车离开车位

27号车离开车位

29号车离开车位

10 个停车位可以用!

三. Semaphore vs. CountDownLatch

相同点:

两者都是用于线程同步的工具类,都通过定义了一个继承AbstractQueuedSynchronizer的内部类Sync来实现具体的功能。

不同点:

1.Semaphore提供了公平和非公平两种策略, 而CountDownLatch则不具备。

2.CountDownLatch: 一个或者是一部分线程,等待另外一部线程都完成操作。

Semaphorr:维护一个许可集.通常用于限制可以访问某些资源(物理或逻辑的)的线程数目。

3.CountDownLatch中计数是不能被重置的。CountDownLatch适用于一次同步。当使用CountDownLatch时,任何线程允许多次调用countDown()。那些调用了await()方法的线程将被阻塞,直到那些没有被阻塞线程调用countDown()使计数到达0为止。

Semaphore允许线程获取许可, 未获得许可的线程需要等待.这样防止了在同一时间有太多的线程执行.Semaphore的值被获取到后是可以释放的,并不像CountDownLatch那样一直减到0。

4.使用CountDownLatch时,它关注的一个线程或者多个线程需要在其它在一组线程完成操作之后,在去做一些事情。比如:服务的启动等。使用Semaphore时,它关注的是某一个资源最多同时能被几个线程访问。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值