使用executor服务在JavaSwing上实现光线跟踪并行计算

使用executor服务在JavaSwing上实现光线跟踪并行计算,java,multithreading,swing,raytracing,Java,Multithreading,Swing,Raytracing,我在这里看到很多线程只讨论sudo算法如何实现光线跟踪的视差,我很难实现它 我目前的做法如下 ExecutorService fixedPool=Executors.newFixedThreadPool(/*don't know whats the best value for my system without crashing it*/); private static final class DrawCall { private final int x,y; private java

我在这里看到很多线程只讨论sudo算法如何实现光线跟踪的视差,我很难实现它

我目前的做法如下

ExecutorService fixedPool=Executors.newFixedThreadPool(/*don't know whats the best value for my system without crashing it*/);

private static final class DrawCall
{
 private final int x,y;
 private java.awt.Color pixelColor;

 private DrawCall(int x,int y,Color color)
 {
  this.x=x;
  this.y=y;
  this.color=color;
 }

 private void draw(Graphics2D g2d)
 {
  g2d.setColor(color);
  g2d.fillRect(x,y,1,1);
 }
}

@Override
public void paintComponent(Graphics g)
{
 ArrayList<Future<DrawCall>> calls=new ArrayList();//An Future for every pixel

 for(int x=0;x<width;x++)
 {
  for(int y=0;y<height;y++)
  {
   Future<DrawCall> call=fixedPool.submit(
                   ()->
                   {
                     //My ray tracing per pixel submitted as an lambda task to the executor service

                    if(intersection with scene){return new DrawCall(x,y,/*pixel color at that point*/);}
                    else{return null;//no op}
                   }
                  );

   calls.add(call);
  }
 }
  
 while(!calls.isEmpty())
 {
  calls.removeIf(callBack->
  {
   if(callBack.isDone())
   {
    DrawCall call=callBack.get();
    if(call!=null){call.draw((Graphics2D)g);}
   }  
   return callBack.isDone();
  });
 }
}
ExecutorService fixedPool=Executors.newFixedThreadPool(/*不知道我的系统在不崩溃的情况下有什么最佳价值*/);
私有静态最终类调用
{
私人最终整数x,y;
private java.awt.Color pixelColor;
私人DrawCall(整数x,整数y,彩色)
{
这个.x=x;
这个。y=y;
这个。颜色=颜色;
}
专用空心图纸(Graphics2D g2d)
{
g2d.setColor(彩色);
g2d.fillRect(x,y,1,1);
}
}
@凌驾
公共组件(图形g)
{
ArrayList calls=new ArrayList();//每个像素的未来
对于(int x=0;x
{
if(callBack.isDone())
{
DrawCall=callBack.get();
if(call!=null){call.draw((Graphics2D)g);}
}  
返回callBack.isDone();
});
}
}
这根本不能提高性能

我还尝试将每个像素(在executor服务中渲染)渲染为一个缓冲图像[synchronized on it],然后调用JPanel的repaint()[using SwingUtilities.invokeLater()]在屏幕上绘制每个像素都已完成的图像,但性能进一步恶化


对于我的作业,我只允许使用java swing,那么什么是将像素尽快平行地推送到屏幕上的最佳方法?

查看ImageRaster以及如何有效地写入swingimages@Polygnome我确实使用了附加到缓冲映像的方法,但它的所有方法都不是线程安全的,因此我必须在它上进行同步,当有1000+时试图获得单个光栅性能的线程会受到影响。正如我所发现的那样,在JPanel上用每一个像素重新绘制BuffereImage,调用repaint一千次或更多次也是一个糟糕的想法:(查看ImageRaster以及如何有效地写入Swingimages@Polygnome我确实使用了附加到缓冲图像的方法,但它的所有方法都不是线程安全的,因此我必须在其上进行同步,当有1000多个线程试图获取单个光栅时,性能会受到影响。还调用了数千次或更多次重新绘制缓冲图像我发现JPanel上的每一个像素都是一个可怕的想法:(