导读:本期聚焦于小伙伴创作的《Java多线程同步中如何使用Semaphore实现交替执行与共享资源管理》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《Java多线程同步中如何使用Semaphore实现交替执行与共享资源管理》有用,将其分享出去将是对创作者最好的鼓励。

Semaphore是Java并发包java.util.concurrent下的一个同步工具类,它通过维护一组许可证来控制对共享资源的访问权限,线程在访问资源前需要先获取许可证,访问完成后释放许可证,当许可证不足时线程会被阻塞等待。这种机制既可以限制同时访问共享资源的线程数量,也能通过许可证的分配逻辑实现线程间的交替执行。

Java多线程同步中如何使用Semaphore实现交替执行与共享资源管理

Semaphore核心方法说明

Semaphore的常用构造方法和方法如下:

  • Semaphore(int permits):创建指定许可证数量的Semaphore,默认采用非公平模式
  • Semaphore(int permits, boolean fair):创建指定许可证数量的Semaphore,fair为true时采用公平模式,线程按等待顺序获取许可证
  • acquire():从Semaphore中获取一个许可证,若没有可用许可证则当前线程阻塞
  • release():释放一个许可证,将其返回给Semaphore
  • availablePermits():返回当前可用的许可证数量

使用Semaphore实现两个线程交替执行

交替执行的核心思路是为两个线程分别分配不同的Semaphore,初始时只给第一个线程的Semaphore发放许可证,第一个线程执行完成后释放第二个线程的Semaphore许可证,同时释放自身的许可证,以此类推实现交替逻辑。

以下示例实现线程A和线程B交替打印数字:

import java.util.concurrent.Semaphore;

public class SemaphoreAlternateDemo {
    // 控制线程A的Semaphore,初始发放1个许可证
    private static Semaphore semaphoreA = new Semaphore(1);
    // 控制线程B的Semaphore,初始不发放许可证
    private static Semaphore semaphoreB = new Semaphore(0);
    // 打印次数
    private static final int PRINT_COUNT = 5;

    static class ThreadA extends Thread {
        @Override
        public void run() {
            try {
                for (int i = 0; i < PRINT_COUNT; i++) {
                    // 获取线程A的许可证
                    semaphoreA.acquire();
                    System.out.println("线程A打印: " + i);
                    // 释放线程B的许可证
                    semaphoreB.release();
                }
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
    }

    static class ThreadB extends Thread {
        @Override
        public void run() {
            try {
                for (int i = 0; i < PRINT_COUNT; i++) {
                    // 获取线程B的许可证
                    semaphoreB.acquire();
                    System.out.println("线程B打印: " + i);
                    // 释放线程A的许可证
                    semaphoreA.release();
                }
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
    }

    public static void main(String[] args) {
        new ThreadA().start();
        new ThreadB().start();
    }
}

运行上述代码可以看到线程A和线程B交替输出内容,执行逻辑为:线程A初始有许可证可以执行,执行后释放线程B的许可证,此时线程A的许可证被释放后重新可用,线程B获取许可证执行后释放线程A的许可证,循环往复直到打印次数完成。

使用Semaphore管理共享资源访问

当有多个线程需要访问同一个共享资源,且需要限制同时访问的线程数量时,可以使用Semaphore控制并发数。例如数据库连接池、文件读写等场景,都可以用Semaphore限制同时操作的线程数。

以下示例模拟限制同时访问共享资源的线程数为3:

import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;

public class SemaphoreResourceDemo {
    // 共享资源,模拟需要限制访问的资源
    private static final String SHARED_RESOURCE = "共享资源实例";
    // Semaphore,初始3个许可证,最多允许3个线程同时访问
    private static Semaphore semaphore = new Semaphore(3);

    static class WorkerThread extends Thread {
        private String threadName;

        public WorkerThread(String threadName) {
            this.threadName = threadName;
        }

        @Override
        public void run() {
            try {
                System.out.println(threadName + " 尝试获取资源访问权限");
                // 获取许可证,最多等待2秒
                if (semaphore.tryAcquire(2, TimeUnit.SECONDS)) {
                    try {
                        System.out.println(threadName + " 成功获取权限,开始访问资源: " + SHARED_RESOURCE);
                        // 模拟资源访问耗时
                        TimeUnit.SECONDS.sleep(1);
                        System.out.println(threadName + " 访问资源完成");
                    } finally {
                        // 释放许可证
                        semaphore.release();
                        System.out.println(threadName + " 释放资源访问权限,当前可用许可证数: " + semaphore.availablePermits());
                    }
                } else {
                    System.out.println(threadName + " 获取权限超时,无法访问资源");
                }
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
    }

    public static void main(String[] args) {
        // 创建6个线程尝试访问资源
        for (int i = 0; i < 6; i++) {
            new WorkerThread("线程" + i).start();
        }
    }
}

运行代码可以看到最多同时有3个线程访问共享资源,其余线程需要等待许可证释放后才能获取访问权限,有效避免了过多线程同时访问资源导致的性能问题或资源冲突。

使用Semaphore的注意事项

  • 如果使用tryAcquire方法获取许可证,需要在finally块中确保许可证被释放,避免许可证泄露导致后续线程无法获取权限
  • 公平模式虽然可以避免线程饥饿,但会带来额外的性能开销,非必要场景建议使用非公平模式
  • Semaphore的许可证数量可以动态变化,release方法可以释放多个许可证,也可以超过初始设置的许可证数量,使用时需要注意逻辑合理性
  • 不要在获取许可证后长时间阻塞线程,否则会导致其他等待的线程长时间无法获取权限,影响程序整体性能

JavaSemaphore多线程同步共享资源管理修改时间:2026-06-11 09:00:18

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。