cover

在Java中,你可以使用java.util.concurrent.Semaphore类来实现信号量。信号量是一种用于控制并发访问的同步工具,它可以限制同时访问某个资源的线程数量。

下面是一个使用信号量的简单示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
import java.util.concurrent.Semaphore;

public class SemaphoreExample {
public static void main(String[] args) {
// 创建一个信号量,初始许可数量为2
Semaphore semaphore = new Semaphore(2);

// 创建并启动5个线程
for (int i = 1; i <= 5; i++) {
Thread thread = new Thread(new Worker(semaphore, i));
thread.start();
}
}

static class Worker implements Runnable {
private Semaphore semaphore;
private int id;

public Worker(Semaphore semaphore, int id) {
this.semaphore = semaphore;
this.id = id;
}

@Override
public void run() {
try {
System.out.println("线程 " + id + " 正在获取许可...");
semaphore.acquire(); // 获取许可

System.out.println("线程 " + id + " 已获取许可,正在执行任务...");
Thread.sleep(2000); // 模拟执行任务的耗时

System.out.println("线程 " + id + " 任务执行完毕,释放许可...");
semaphore.release(); // 释放许可
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

在上面的示例中,我们创建了一个初始许可数量为2的信号量。然后,我们创建了5个线程,每个线程都尝试获取许可并执行任务。由于信号量的许可数量为2,因此最多只有2个线程可以同时获取许可并执行任务,其他线程必须等待。

输出可能是这样的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
线程 1 正在获取许可...
线程 1 已获取许可,正在执行任务...
线程 2 正在获取许可...
线程 2 已获取许可,正在执行任务...
线程 3 正在获取许可...
线程 4 正在获取许可...
线程 5 正在获取许可...
线程 1 任务执行完毕,释放许可...
线程 2 任务执行完毕,释放许可...
线程 3 已获取许可,正在执行任务...
线程 4 已获取许可,正在执行任务...
线程 3 任务执行完毕,释放许可...
线程 4 任务执行完毕,释放许可...
线程 5 已获取许可,正在执行任务...
线程 5 任务执行完毕,释放许可...

注意,使用信号量时要确保在适当的时候释放许可,否则可能导致其他线程无法获取许可而一直等待。在上面的示例中,我们使用semaphore.release()在任务执行完毕后释放许可。

除了信号量 (Semaphore),在 Java 中还有许多常用的类,用于实现并发和多线程编程。以下是一些常见的类:

  • java.util.concurrent.Semaphore: 信号量是一种用于控制并发访问的同步工具,它可以限制同时访问某个资源的线程数量

  • java.util.concurrent.ConcurrentHashMap:线程安全的哈希表实现,可以在多线程环境下进行并发操作。

  • java.util.concurrent.CountDownLatch:倒计时门闩,用于等待一组线程完成某个任务。

  • java.util.concurrent.CyclicBarrier:循环屏障,用于等待一组线程到达某个屏障点,然后同时执行下一步操作。

  • java.util.concurrent.Exchanger:线程间交换数据的同步点,用于两个线程之间交换对象。

  • java.util.concurrent.Executor:执行任务的接口,常用的实现类有 ThreadPoolExecutor 和 ScheduledThreadPoolExecutor。

  • java.util.concurrent.Future:表示异步计算的结果,可以用于获取任务的执行结果。

  • java.util.concurrent.locks.Lock:提供了比 synchronized 关键字更灵活的锁机制,常用的实现类有 ReentrantLock 和 ReadWriteLock。

  • java.util.concurrent.atomic.AtomicXXX:提供了原子操作的类,用于在多线程环境下进行高效的原子操作。