Semaphore详解1

本文介绍Semaphore类的基本使用方法,通过示例代码展示了如何利用Semaphore控制线程并发数量,确保资源的有效利用并避免线程间的数据冲突。

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

Semaphore类其实就是synchronized关键字的升级版,这个类主要作用就是控制线程并发的数量,而在这方面synchronized就有点力不足了,接下来我们就开始先了解一下Semaphore的一些常用方法就注意细节。

在new 这个类的时候需要给这个类传递一个参数permits,这个参数是整数类型,这个参数的意思是同一时间内,最多允许多少个线程同时执行acquire方法和release方法之间的代码,如果方法acquire没有参数则默认是一个许可。下面我们用代码进行验证。

步骤:

1,创建一个工程,我的工程目录如下图


2,创建一个类,(我这里的类名是TestSemaphore)这个类用于实例化Semaphore类,并确定线程需要执行的代码。

package cn.wxz.test;

import java.util.concurrent.Semaphore;

public class TestSemaphore {
	Semaphore semaphore= new Semaphore(1);
	public void  test(){
		
		try {
			semaphore.acquire();
			System.err.println(Thread.currentThread().getName()+"开始运行时间"+System.currentTimeMillis());
			Thread.sleep(1000);
			System.err.println(Thread.currentThread().getName()+"结束运行时间"+System.currentTimeMillis());
			semaphore.release();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
}
3,接下来创建三个类(testThread1,testThread2,testThread3)这三个类基本上都是一样的,这三个类都继承Thread

  3.1 testThread1代码如下:

package cn.wxz.test;

public class testThread1 extends Thread {
    private TestSemaphore testSemaphore;
	
    public testThread1(TestSemaphore testSemaphore){
    	this.testSemaphore=testSemaphore;
    }
    @Override
    public void run() {
 
    	super.run();
    	testSemaphore.test();
    }
}
3.2testThread2代码如下:

package cn.wxz.test;

public class testThread2 extends Thread {
    private TestSemaphore testSemaphore;
	
    public testThread2(TestSemaphore testSemaphore){
    	this.testSemaphore=testSemaphore;
    }
    @Override
    public void run() {
 
    	super.run();
    	testSemaphore.test();
    }
}
3.3testThread3代码如下:
package cn.wxz.test;

public class testThread3 extends Thread {
    private TestSemaphore testSemaphore;
	
    public testThread3(TestSemaphore testSemaphore){
    	this.testSemaphore=testSemaphore;
    }
    @Override
    public void run() {
 
    	super.run();
    	testSemaphore.test();
    }
}

最后创建一个测试类Test代码如下:

package cn.wxz.test;

public class Test {
	public static void main(String[] args) {
		TestSemaphore testSemaphore = new TestSemaphore();
		testThread1 testThread1 = new testThread1(testSemaphore);
		testThread1.setName("我的线程名变成了1");
		testThread2 testThread2 = new testThread2(testSemaphore);
		testThread2.setName("我的线程名变成了2");
		testThread3 testThread3 = new testThread3(testSemaphore);
		testThread3.setName("我的线程名变成了3");
		testThread1.start();
		testThread2.start();
		testThread3.start();
	}
	
}

运行结果如下图:

由运行结果可以得出我们之前提出的 Semaphore semaphore= new Semaphore(1);这个参数是同一时间内,最多允许多少个线程同时执行acquire方法和release方法之间的代码,得到验证,大家可以通过改变new Semaphore(1);的参数来验证结果,这里大家需要注意,这个参数的值如果大于1时,该类不能保证线程安全,因为这有可能会出现多个线程共同访问实例变量,导致出现脏数据。


### Python `multiprocessing` 中 `Semaphore` 的使用详解 #### 什么是 `Semaphore` `Semaphore` 是一种同步原语,用于控制对共享资源的并发访问。它可以限制同时进入某个临界区的线程或进程数量。通过初始化时指定的一个计数值,`Semaphore` 可以允许多个进程/线程竞争同一资源[^1]。 当一个进程调用 `acquire()` 方法时,如果当前可用的信号量大于零,则该进程会获得信号量并将其减一;否则,该进程会被阻塞直到有其他进程释放信号量(即调用 `release()` 方法)[^2]。 #### 原理分析 - **初始值设置**:在创建 `Semaphore` 对象时可以通过参数设定其最大允许同时运行的任务数。 - **获取资源 (`acquire`) 和释放资源 (`release`)**: - 调用 `acquire()` 表示请求占用一个单位的资源。 - 如果此时剩余可分配资源不足,则调用方将被挂起等待。 - 当不再需要此资源时应显式地调用 `release()` 来归还所占有的资源单元给系统以便后续任务能够继续执行下去[^3]。 #### 示例代码展示 以下是基于官方文档以及实际应用场景构建的一段演示如何利用 `multiprocessing.Semaphore` 实现多进程之间协调工作的例子: ```python from multiprocessing import Semaphore, Process import time def task(name, sem): """模拟耗时操作""" print(f"{name}: 尝试获取信号量...") # 请求获取信号量 sem.acquire() try: print(f"{name}: 成功获取到信号量.") # 模拟业务逻辑处理过程 time.sleep(2) print(f"{name}: 完成工作.") finally: # 不管发生什么情况都要记得释放信号量 sem.release() if __name__ == "__main__": # 创建一个只允许两个进程同时进入的关键区域 semaphore = Semaphore(2) jobs = [] for i in range(5): job = Process(target=task, args=(f"Worker-{i}", semaphore)) jobs.append(job) job.start() for j in jobs: j.join() ``` 在这个脚本里我们定义了一个名为 `task` 的函数代表每一个独立的工作项,在这个过程中它们都需要先尝试取得由变量 `semaphore` 所表示的那个互斥锁才能正式开始自己的主要活动——这里为了简化描述就让每个工作者睡两秒钟作为他们各自要做的具体事情。注意每次循环都会新启一个新的子进程来负责不同的实例化后的作业对象,并且最后还要确保主线程等到所有的这些分支都结束了才退出整个应用程序。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值