java为什么不使用多个线程进行加速?
我正在使用synchronized block用java创建一个玩具程序。我有n个“Pixelator”线程,它们在1000x1000图像中随机选取一个像素,并将其指定给Pixelator的颜色。每个像素只能指定一次。我使用包装器类写入BuffereImage,该类使用同步方法写入映像。然而,当我使用超过1个线程进行测试时,我没有看到加速。你知道为什么会这样吗
相关代码:
import java.awt.Color;
import java.awt.image.*;
import java.io.*;
import javax.imageio.*;
import java.util.ArrayList;
import java.util.Random;
public class q2 {
// The image constructed
public static BufferedImage img;
// Image dimensions; you could also retrieve these from the img object.
public static int width;
public static int height;
// simplified method for stack overflow example
public static int rgbFromN(int n) {
return -16755216;
}
public static void main(String[] args) {
Random r = new Random();
try {
// arg 0 is the width
width = 1000;
// arg 1 is the height
height = 1000;
// arg 2 is the number of threads
int nt = 1;
// create an image and initialize it to all 0's
img = new BufferedImage(width,height,BufferedImage.TYPE_INT_ARGB);
synchronizedIMG simg = new synchronizedIMG(img);
for (int i=0;i<width;i++) {
for (int j=0;j<height;j++) {
img.setRGB(i,j,0);
}
}
Thread[] threads = new Thread[nt];
long startTime = System.currentTimeMillis();
for (int i = 0; i < threads.length; i++) {
threads[i] = new Thread(new Pixelator(rgbFromN(i),width,height,((width*height)/nt),simg));
threads[i].start();
}
for (int i = 0; i < threads.length; i++) {
threads[i].join();
}
long endTime = System.currentTimeMillis();
System.out.println("Time(ms): " + (endTime-startTime));
// Write out the image
File outputfile = new File("outputimage.png");
ImageIO.write(img, "png", outputfile);
} catch (Exception e) {
System.out.println("ERROR " +e);
e.printStackTrace();
}
}
}
class Pixelator implements Runnable {
int color;
int width;
int height;
int numPixels;
int currentPixels = 0;
synchronizedIMG simg;
public Pixelator(int color, int width, int height,int numPixels, synchronizedIMG simg){
this.color = color;
this.width = width;
this.height = height;
this.numPixels = numPixels;
this.simg = simg;
}
public void run() {
int randomX = 0;
int randomY = 0;
boolean success = false;
while(currentPixels < numPixels){
randomX = 0 + (int)(Math.random() * (width));
randomY = 0 + (int)(Math.random() * (height));
success = simg.setColor(color, randomX, randomY);
if(success){
currentPixels++;
}
}
return;
}
}
class synchronizedIMG{
BufferedImage img;
public synchronizedIMG(BufferedImage img){
this.img = img;
}
public synchronized boolean setColor(int color, int x, int y){
if(img.getRGB(x, y) == 0){
img.setRGB(x, y, color);
return true;
} else{
return false;
}
}
}
# 1 楼答案
您面临的最大问题是,添加更多线程不会增加系统的内存带宽
你的线程除了计算随机数并将其写入内存之外什么都不做。添加更多线程可能会提高计算随机数的速度,但一开始可能非常快。数学random()不是加密质量的随机数生成器。它可能非常快
不幸的是,直到所有字节都被写入内存,你的工作才完成。你的系统只有一条内存总线,而且它只能运行得很快。所有线程都必须争夺该资源
# 2 楼答案
机器需要一定的时间来管理线程。在图像处理中,使用两个线程而不是一个线程,不会减少50%的处理时间,但根据处理情况(使用我自己的java库中的多线程类进行经验估计)可以减少30%到40%
此外,在你的例子中,你不需要做任何主要的处理,只需要简单的计算。因此,管理线程比在单个线程上处理要长。试着做一个大的卷积