现在我来讲解一下"Java多线程之Semaphore实现信号灯"的完整攻略。在Java多线程编程中,Semaphore可以用来控制多个线程需要访问的资源的数量,Semaphore允许多个线程同时访问某一个资源,但需要限制其同时访问的数量。
Semaphore的基本用法
Semaphore的构造方法:
public Semaphore(int permits)
其中permits表示同时能够访问某一个资源的线程数目。
Semaphore的两个基本方法:
public void acquire() throws InterruptedException
public void release()
其中acquire方法会获取Semaphore的许可,如果没有足够的许可,则会进入等待状态;release方法会释放Semaphore的许可。
Semaphore的应用场景:
Semaphore常用于多个共享资源的互斥使用。例如,读写线程都要访问同一个文件,但是需要限制同时访问该文件的线程数量。
示例一:访问共享资源
下面我们以读写线程访问文件的示例来说明Semaphore的应用。
import java.util.concurrent.Semaphore;
public class ReadWriteFile {
private Semaphore readSemaphore = new Semaphore(5); // 读许可证
private Semaphore writeSemaphore = new Semaphore(1); // 写许可证
public void read() throws InterruptedException {
readSemaphore.acquire(); // 获取读许可证
// 读文件
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName() + "读了文件");
readSemaphore.release(); // 释放读许可证
}
public void write() throws InterruptedException {
writeSemaphore.acquire(); // 获取写许可证
// 写文件
Thread.sleep(2000);
System.out.println(Thread.currentThread().getName() + "写了文件");
writeSemaphore.release(); // 释放写许可证
}
public static void main(String[] args) throws InterruptedException {
ReadWriteFile rwf = new ReadWriteFile();
// 多个读线程
for (int i = 0; i < 10; i++) {
new Thread(() -> {
try {
rwf.read();
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "reader " + i).start();
}
// 一个写线程
new Thread(() -> {
try {
rwf.write();
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "writer").start();
}
}
上述代码中,read和write方法表示读和写文件。在构造方法中,我们定义了读许可证和写许可证,读许可证可以有5个,写许可证只能有一个。在读文件时,需要读许可证,如果没有足够的读许可证,则线程进入等待状态;在写文件时,需要写许可证,如果没有写许可证,则线程进入等待状态。
上述代码中,我们同时创建10个读线程和1个写线程。根据定义,每次最多只能有5个读线程同时访问文件,只能有一个线程写文件。我们可以运行代码,并观察10个读线程和1个写线程的执行情况。
示例二:限制系统资源
下面我们以限制系统资源数量的示例来说明Semaphore的应用。
import java.util.concurrent.Semaphore;
public class SemaphoreTest {
public static void main(String[] args) {
Semaphore semaphore = new Semaphore(2); // 限制系统中最多只能有两个进程并发执行
// 创建10个线程模拟进程
for (int i = 0; i < 10; i++) {
new Thread(() -> {
try {
semaphore.acquire(); // 获取许可证
System.out.println(Thread.currentThread().getName() + "获得许可证,开始执行");
Thread.sleep(1000); // 模拟进程执行的时间
semaphore.release(); // 释放许可证
System.out.println(Thread.currentThread().getName() + "释放许可证,执行结束");
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "Process " + i).start(); // 线程命名为Process0,Process1....Process9
}
}
}
上述代码中,Semaphore的初始值为2,表示系统中最多只能有两个进程并发执行。在创建10个线程模拟进程时,每个线程首先获取许可证,如果已经有2个线程在执行,则该线程进入等待状态。当其他线程释放许可证时,当前线程获取到许可证,开始执行进程操作。
上述代码中,我们可以运行代码,并观察10个线程的执行情况。
总结
通过本文的讲解,我们了解了Semaphore在多线程编程中的应用,Semaphore可以用来控制线程对资源的访问数量。Semaphore通过acquire方法获取许可证,通过release方法释放许可证。
在实际应用中,我们可以用Semaphore来实现读写锁、限制系统资源并发执行的数量等。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java多线程之Semaphore实现信号灯 - Python技术站