获取 java.io.IOException: 每当我关闭我的程序时关闭

Getting java.io.IOException: closed whenever I close my program

每次我 运行 我的程序都 运行 没问题。但是当我在 运行 运行程序几秒钟后关闭它时,我得到了 java.io.IOException: closed 错误。我试过环顾四周,找不到解决办法。我能找到的唯一解决办法就是不在 try-catch 块中使用 e.printstacktrace,但这显然不能解决问题。这是代码:

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

import javax.imageio.ImageIO;

public class Main extends Canvas implements Runnable{

    private static final long serialVersionUID = -661485289446387445L;
    private Thread thread;
    public int blackPos;
    public int whitePos;
    public boolean isWhiteTurn; // In single player this determines board orientation, in multiplayer it doesn't
    public boolean running; 
    public final int HEIGHT = 800;
    public final int WIDTH = 1200;
    //public File[] imgSrc = {new File("/images/urBoard.png"), new File("/rsc/urBackground.jpg")};
    public BufferedImage[] img = new BufferedImage[2];
    public Board board;
    
    public Main() {
        new Window(WIDTH, HEIGHT, this);
        board = new Board(this);
    }
    
    
     public void run()
      {
        requestFocus();
        long lastTime = System.nanoTime();
        double amountOfTicks = 60.0D;
        double ns = 1.0E9D / amountOfTicks;
        double delta = 0.0D;
        long timer = System.currentTimeMillis();
        int frames = 0;
        while (this.running)
        {
          long now = System.nanoTime();
          delta += (now - lastTime) / ns;
          lastTime = now;
          while (delta >= 1.0D)
          {
            tick();
            delta -= 1.0D;
          }
          if (this.running) {
            render();
          }
          frames++;
          if (System.currentTimeMillis() - timer > 1000L)
          {
            timer += 1000L;
            System.out.println("FPS: " + frames);
            frames = frames;
            frames = 0;
          }
        }
      
      }
     
     public synchronized void start() {
         thread = new Thread(this);
         thread.start();
         running=true;
         
     }
     public synchronized void stop() {
            try
            {
              this.thread.join();
              this.running = false;
            }
            catch (Exception e)
            {
              e.printStackTrace();
            }
         
     }
    
     public void tick() {
        board.tick();
     }
     
    public void render() {
        BufferStrategy bs = getBufferStrategy();
        if(bs == null) {
            createBufferStrategy(3);
            return;
        }
        
        try {
            img[0] = ImageIO.read(getClass().getResource("/rsc/urBoard.png"));
            img[1] = ImageIO.read(getClass().getResource("/rsc/urBackground.jpg"));
        } catch (IOException e) {
            e.printStackTrace();
        }
        
        Graphics g = bs.getDrawGraphics();
        
        g.drawImage(img[1], 0, 0, WIDTH, HEIGHT, null);
        g.setColor(Color.GREEN);
        g.drawLine(200, 0, 200, 800);
        g.setFont(new Font("times new roman", Font.BOLD, 30)); 
        g.drawString("END PIECES", 10, 30); 
        
        board.render(g);
        
        g.dispose();
        bs.show();
        
    }
    
    public static void main(String[] args) {
        
        new Main();

    }

}

这是我在 运行 几秒钟后关闭 GUI 时遇到的错误:

java.io.IOException: closed
    at javax.imageio.stream.ImageInputStreamImpl.checkClosed(ImageInputStreamImpl.java:110)
    at javax.imageio.stream.ImageInputStreamImpl.close(ImageInputStreamImpl.java:857)
    at javax.imageio.stream.FileCacheImageInputStream.close(FileCacheImageInputStream.java:250)
    at javax.imageio.ImageIO.read(ImageIO.java:1451)
    at javax.imageio.ImageIO.read(ImageIO.java:1400)
    at main.Main.render(Main.java:99)
    at main.Main.run(Main.java:54)
    at java.lang.Thread.run(Thread.java:745)

我注意到,如果我在启动程序后立即关闭 window,则不会出现错误。只有当我 运行 程序运行大约 3-4 秒,然后我关闭 window 时,它才会出现。什么会导致这种情况发生,解决方法是什么?

关闭应用程序时,您的 render() 方法可能是 运行。由于您的资源在 render() 调用之间没有变化,因此将此块移动到 Main() 构造函数的开头,以便 img[] 设置一次,如果找不到资源则抛出异常:

try {
    img[0] = ImageIO.read(getClass().getResource("/rsc/urBoard.png"));
    img[1] = ImageIO.read(getClass().getResource("/rsc/urBackground.jpg"));
} catch (IOException e) {
    throw new RuntimeException("Could not find resources");
}

字段running在不同的线程中使用所以应该标记volatile以便每个线程读取一致的值:

public volatile boolean running;