创建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
相关产品推荐
相关产品推荐

