You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java多线程同步:同父类乐器实例互斥实现方案咨询

嘿,我来帮你解决这个同一父类下乐器实例互斥演奏的问题!

核心思路很明确:给每个抽象父类(String、Wind、Arc)分配一个类级别的独占锁,这样同一父类的所有乐器实例在执行演奏逻辑时,必须先抢到这个锁才能运行,自然就保证了同一时间只有一个实例演奏。

因为你的子类都没重写run()方法,所以我们只需要在三个抽象父类的run()里加锁逻辑就行,具体步骤和代码示例如下:

1. 改造抽象父类的run()方法

每个抽象父类的run()方法中,使用自身的Class对象作为类级锁,把核心的演奏逻辑包裹在synchronized块里。这样同一父类的所有实例都会竞争这同一个锁,实现互斥执行。

以Wind类为例:

public abstract class Wind extends Thread {
    @Override
    public void run() {
        // 使用Wind类对象作为类级锁,同一父类的所有实例共享这个锁
        synchronized (Wind.class) {
            // 调用子类实现的演奏逻辑
            play();
        }
    }

    // 抽象演奏方法,由子类具体实现
    public abstract void play();
}

同理,String和Arc类做完全相同的改造,只需要把锁对象换成String.class和Arc.class即可。

2. 乐器子类示例

比如一个属于Wind子类的长笛:

public class Flute extends Wind {
    @Override
    public void play() {
        System.out.println(Thread.currentThread().getName() + " 正在吹奏长笛...");
        try {
            // 模拟演奏时长
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        System.out.println(Thread.currentThread().getName() + " 长笛演奏结束");
    }
}

再比如属于String子类的小提琴:

public class Violin extends String {
    @Override
    public void play() {
        System.out.println(Thread.currentThread().getName() + " 正在拉小提琴...");
        try {
            Thread.sleep(1500);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        System.out.println(Thread.currentThread().getName() + " 小提琴演奏结束");
    }
}
3. 测试Main类验证效果

我们可以创建多个同一父类的实例,启动线程看看互斥效果:

public class Main {
    public static void main(String[] args) {
        // Wind类的两个实例:长笛和萨克斯
        Thread flute = new Flute();
        flute.setName("长笛线程");
        Thread saxophone = new Saxophone();
        saxophone.setName("萨克斯线程");

        // String类的两个实例:小提琴和吉他
        Thread violin = new Violin();
        violin.setName("小提琴线程");
        Thread guitar = new Guitar();
        guitar.setName("吉他线程");

        // 启动所有线程
        flute.start();
        saxophone.start();
        violin.start();
        guitar.start();
    }
}

运行后你会看到:

  • 长笛和萨克斯不会同时演奏,必须等其中一个结束后另一个才开始
  • 小提琴和吉他不会同时演奏,但它们可以和长笛/萨克斯同时进行(因为用的是不同的类锁)
方案可行性说明
  • 类锁(Xxx.class)属于类本身,所有该类的实例共享这一个锁,所以同一父类的实例会互斥执行synchronized块里的代码
  • 不同父类的锁是各自独立的,所以不同类型的乐器可以同时演奏,不会互相影响
  • 因为子类没有重写run(),所以父类的锁逻辑会被所有子类继承,不需要修改子类代码,完全符合你的需求

内容的提问来源于stack exchange,提问作者Nicola Bernardi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 06:52:46