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

创建ReaderWriter类实例报错:无法访问Reader的封闭实例

问题描述

尝试在main方法中通过ReaderWriter readerWriter = new ReaderWriter();创建ReaderWriter类实例时,出现错误:

No enclosing instance of type Reader is accessible. Must qualify the allocation with an enclosing instance of type Reader (e.g. x.new A() where x is an instance of Reader).

完整代码如下:

import BSsync.Lock;
import BSsync.Condition;

class File {
    String content = "";
}

class Reader extends Thread {
    ReaderWriter readerWriter;
    String identifier;

    public Reader (String identifier, ReaderWriter readerWriter) {
        this.identifier = identifier;
        this.readerWriter = readerWriter;
    }

    public void run () {
        for (int i = 0; i < 10; i++) {
            String message = readerWriter.read(identifier);
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    class Writer extends Thread {
        ReaderWriter readerWriter;
        String identifier;

        public Writer (String identifier, ReaderWriter readerWriter) {
            this.identifier = identifier;
            this.readerWriter = readerWriter;
        }

        public void run() {
            for (int i = 0; i < 10; i++) {
                String message = "Message " + i + " of writer " + identifier;
                readerWriter.write(message);
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    class  ReaderWriter {
        final static int MAX_READERS = 3;

        Lock mutex = new Lock();
        Condition okToWrite = mutex.newCondition();
        Condition maxReaders = mutex.newCondition();
        int activeReaders = 0;
        boolean busy = false;
        File file = new File();

        public String read (String identifierOfReader) {
            readStart();
            String result = file.content;
            System.out.println("\tReader " + identifierOfReader + " has read: " + result);
            readStop();
            return result;
        }

        public void write (String content) {
            writeStart();
            System.out.println(content + " was written");
            file.content = content;
            writeStop();
        }

        private void readStart() {
            mutex.lock();
            
            while (busy) {
                okToWrite.await();
            }
            
            while (activeReaders + 1 > MAX_READERS) {
                maxReaders.await();
            }
            
            activeReaders++;
            mutex.unlock();
        }

        private void readStop() {
            mutex.lock();
            activeReaders--;
            maxReaders.signalAll();
            if (activeReaders == 0) {
                okToWrite.signalAll();
            }
            mutex.unlock();
        }

        private void writeStart() {
            mutex.lock();
            while (busy || activeReaders > 0) {
                okToWrite.await();
            }
            busy = true;
            mutex.unlock();
        }

        private void writeStop() {
            mutex.lock();
            busy = false;
            okToWrite.signalAll();
            mutex.unlock();
        }
    
    
        public static void main(String args[]) {
            ReaderWriter readerWriter = new ReaderWriter();
            
            
            Writer writerA = new Writer("A", readerWriter);
            Writer writerB = new Writer("B", readerWriter);
            writerA.start();
            writerB.start();
            
            for (int i = 0; i < 50; i++) {
                Reader r = new Reader(Integer.toString(i), readerWriter);
                r.start();
            }
        }
    }}
问题原因
  • 非静态内部类的实例化限制:ReaderWriter是Reader类的非静态内部类,非静态内部类必须依赖外部类的实例才能创建。而main是静态方法,静态上下文没有Reader的实例,直接调用new ReaderWriter()会触发错误。
  • 连锁依赖问题:Writer同样是Reader的非静态内部类,在main方法中直接实例化也会遇到相同问题;同时Reader的构造需要ReaderWriter实例,ReaderWriter又依赖Reader实例,形成循环依赖。
解决方案

最合理的修复方式是调整类结构,将ReaderWriter、Reader、Writer拆分为独立的顶级类,彻底消除内部类的依赖限制。修改后的代码如下:

import BSsync.Lock;
import BSsync.Condition;

class File {
    String content = "";
}

// 独立的读写控制核心类
class ReaderWriter {
    final static int MAX_READERS = 3;

    Lock mutex = new Lock();
    Condition okToWrite = mutex.newCondition();
    Condition maxReaders = mutex.newCondition();
    int activeReaders = 0;
    boolean busy = false;
    File file = new File();

    public String read(String identifierOfReader) {
        readStart();
        String result = file.content;
        System.out.println("\tReader " + identifierOfReader + " has read: " + result);
        readStop();
        return result;
    }

    public void write(String content) {
        writeStart();
        System.out.println(content + " was written");
        file.content = content;
        writeStop();
    }

    private void readStart() {
        mutex.lock();
        
        while (busy) {
            okToWrite.await();
        }
        
        while (activeReaders + 1 > MAX_READERS) {
            maxReaders.await();
        }
        
        activeReaders++;
        mutex.unlock();
    }

    private void readStop() {
        mutex.lock();
        activeReaders--;
        maxReaders.signalAll();
        if (activeReaders == 0) {
            okToWrite.signalAll();
        }
        mutex.unlock();
    }

    private void writeStart() {
        mutex.lock();
        while (busy || activeReaders > 0) {
            okToWrite.await();
        }
        busy = true;
        mutex.unlock();
    }

    private void writeStop() {
        mutex.lock();
        busy = false;
        okToWrite.signalAll();
        mutex.unlock();
    }

    public static void main(String args[]) {
        ReaderWriter readerWriter = new ReaderWriter();
        
        // 实例化写线程
        Writer writerA = new Writer("A", readerWriter);
        Writer writerB = new Writer("B", readerWriter);
        writerA.start();
        writerB.start();
        
        // 实例化读线程
        for (int i = 0; i < 50; i++) {
            Reader r = new Reader(Integer.toString(i), readerWriter);
            r.start();
        }
    }
}

// 独立的读线程类
class Reader extends Thread {
    ReaderWriter readerWriter;
    String identifier;

    public Reader(String identifier, ReaderWriter readerWriter) {
        this.identifier = identifier;
        this.readerWriter = readerWriter;
    }

    public void run() {
        for (int i = 0; i < 10; i++) {
            String message = readerWriter.read(identifier);
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

// 独立的写线程类
class Writer extends Thread {
    ReaderWriter readerWriter;
    String identifier;

    public Writer(String identifier, ReaderWriter readerWriter) {
        this.identifier = identifier;
        this.readerWriter = readerWriter;
    }

    public void run() {
        for (int i = 0; i < 10; i++) {
            String message = "Message " + i + " of writer " + identifier;
            readerWriter.write(message);
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
修复说明
  • 将三个核心类拆分为独立的顶级类,彻底消除内部类的依赖问题,实例化不再需要外部类对象。
  • 保留原有的读写同步逻辑不变,仅调整类结构,让代码更清晰易维护。
  • main方法可以直接实例化ReaderWriter,再将其传递给Reader和Writer,解决了循环依赖和实例化错误。

内容的提问来源于stack exchange,提问作者Hans Sama

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 09:45:46