Java.util.Concurrent.Semaphore 信号量

本文介绍了一个使用Java的Semaphore类来限制系统资源并发访问的例子。通过创建一个固定大小的信号量,确保只有指定数量的线程能够同时访问共享资源。这有助于避免因过多线程竞争同一资源而导致的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

package com.bjsxt.height.concurrent019;

import java.util.concurrent.ExecutorService;  
import java.util.concurrent.Executors;  
import java.util.concurrent.Semaphore;  
  
/**
 * 可以控制系统的流量,拿到信号量的线程可以进入,否则等待。
          通过 acquire()、release()获取和释放访问许可。
 *
 */
public class UseSemaphore {  
  
    public static void main(String[] args) {  
        // 线程池  
        ExecutorService exec = Executors.newCachedThreadPool();  
        // 只能5个线程同时访问  
        final Semaphore semp = new Semaphore(5);  
        // 模拟20个客户端访问  
        for (int index = 0; index < 20; index++) {  
            final int NO = index;  
            Runnable run = new Runnable() {  
                public void run() {  
                    try {  
                        // 获取许可  
                        semp.acquire();  
                        System.out.println("Accessing: " + NO);  
                        //模拟实际业务逻辑
                        Thread.sleep((long) (Math.random() * 10000));  
                        // 访问完后,释放  
                        semp.release();  
                    } catch (InterruptedException e) {  
                    }  
                }  
            };  
            exec.execute(run);  
        } 
        
        try {
			Thread.sleep(10);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
        
        //System.out.println(semp.getQueueLength());
        
        
        
        // 退出线程池  
        exec.shutdown();  
    }  
  
}  

 

`java.util.concurrent.Semaphore` 是 Java 并发包中的一个同步工具类,它用于控制同时访问某一资源的数量,通过协调多个线程对共享资源的访问。 ### Semaphore 的基本原理 Semaphore 维护了一组许可(permits)。每个 `acquire()` 调用会阻塞直到获取到一个可用的许可,而每次 `release()` 调用则会释放一个许可并将其归还给 semaphore。如果当前没有足够的许可供所有等待的线程使用,则这些线程会被阻塞,直至有足够的许可为止。 #### 主要构造函数及方法: - **构造函数** - `public Semaphore(int permits)` :创建具有给定数量初始许可的 Semaphore 对象。 - **常用方法** - `void acquire() throws InterruptedException`: 获取一个许可,在有可用许可以前一直阻塞。 - `void release()`: 释放一个许可,并唤醒其他正在等待该许可的线程之一。 - `int availablePermits()`: 返回此信号量中当前可用的许可数。 ### 应用场景示例 假设我们有一个应用程序需要限制最多五个线程能够并发地处理任务,此时就可以使用 Semaphore 来实现这种需求。 ```java import java.util.concurrent.*; class TaskProcessor implements Runnable { private final Semaphore semaphore; public TaskProcessor(Semaphore s) { this.semaphore = s; } @Override public void run() { try { // 尝试获得许可 semaphore.acquire(); System.out.println(Thread.currentThread().getName() + " is processing."); Thread.sleep(2000); // 模拟任务处理时间 System.out.println(Thread.currentThread().getName() + " has finished."); // 完成后释放许可 semaphore.release(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } } // 创建允许5个线程同时运行的任务处理器 final int MAX_THREADS = 5; Semaphore semaphore = new Semaphore(MAX_THREADS); for (int i=0;i<10;i++) { new Thread(new TaskProcessor(semaphore)).start(); } ``` 在这个例子中,当第6个线程尝试启动时,由于已经达到了最大并发数目(即semaphore设置的最大值),因此它将被挂起直到之前某个线程完成了工作并且释放了它的许可证。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值