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

Java使用三重BufferStrategy时屏幕撕裂的原因及解决方法

三缓冲出现屏幕撕裂的成因分析

核心原因

  • 双缓冲的垂直同步特性:双缓冲(2个缓冲区)模式下,BufferStrategy.show()会直接交换显示缓冲和后台绘制缓冲。多数操作系统会自动将这个交换操作与显示器的垂直同步(VSync)绑定——只有当显示器完成当前帧的刷新后,才会执行缓冲交换,从根源上避免了屏幕撕裂。
  • 三缓冲的同步逻辑差异:三缓冲(3个缓冲区)包含1个显示缓冲和2个后台缓冲。当你的绘制速度远快于显示器刷新率时,show()方法可能会直接切换到下一个就绪的后台缓冲,跳过垂直同步等待。此时显示器还在显示上一帧的部分内容,新缓冲的画面已经被输出,就会出现撕裂现象。
  • 代码中的额外干扰:你在绘制循环中调用了super.paint(g),这会触发Swing的默认绘制流程,和BufferStrategy的手动缓冲管理机制冲突。这种混用会打乱缓冲的状态管理,进一步放大三缓冲模式下的同步问题。

代码修正方案

1. 移除Swing默认绘制干扰

删掉super.paint(g),改用手动清空画布:

// 用背景色清空整个画布
g.setColor(Color.BLACK);
g.fillRect(0, 0, getWidth(), getHeight());

2. 强制垂直同步

在bufferStrategy.show()之后调用Toolkit.sync(),强制等待显示器垂直同步:

bufferStrategy.show();
Toolkit.getDefaultToolkit().sync();

3. 优化循环控制

添加短暂休眠限制帧率,既减少CPU占用,也避免绘制速度远超刷新率:

try {
    Thread.sleep(16); // 对应约60FPS的刷新率
} catch (InterruptedException e) {
    e.printStackTrace();
}

修正后的完整代码

import java.awt.image.BufferStrategy;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Toolkit;
import javax.swing.JFrame;

public class Shape extends JFrame {
    private Canvas canvas = new Canvas();

    public Shape() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(1000, 800);
        setLocationRelativeTo(null);
        add(canvas);
        setVisible(true);
        canvas.createBufferStrategy(3);

        while (true) {
            BufferStrategy bufferStrategy = canvas.getBufferStrategy();
            Graphics g = bufferStrategy.getDrawGraphics();
            
            // 手动清空画布
            g.setColor(Color.BLACK);
            g.fillRect(0, 0, getWidth(), getHeight());
            
            g.setColor(Color.blue);
            g.fillRect(0, 0, 100, 100);
            
            g.dispose();
            bufferStrategy.show();
            // 强制垂直同步
            Toolkit.getDefaultToolkit().sync();
            
            // 控制帧率
            try {
                Thread.sleep(16);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        new Shape();
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 08:59:20