Java线程-我在写线程安全代码吗?
我目前正在尝试进行并行处理,为此,我正在编写一个程序来处理一幅图像,提供关于其整体颜色值的信息-我正在使用随机生成的整数数组对这一类进行一些测试,从各自的起始位置开始,每4个像素运行4个线程。我只是想知道这是不是线程安全?如果我想要的话,多个线程可以读取相同的数据结构吗Java线程-我在写线程安全代码吗?,java,multithreading,image-processing,colors,Java,Multithreading,Image Processing,Colors,我目前正在尝试进行并行处理,为此,我正在编写一个程序来处理一幅图像,提供关于其整体颜色值的信息-我正在使用随机生成的整数数组对这一类进行一些测试,从各自的起始位置开始,每4个像素运行4个线程。我只是想知道这是不是线程安全?如果我想要的话,多个线程可以读取相同的数据结构吗 import java.awt.image.BufferedImage; import java.lang.Thread; public class ImageProcessor extends Thread {
import java.awt.image.BufferedImage;
import java.lang.Thread;
public class ImageProcessor extends Thread {
public static void main(String[] args) {
int[] z = new int[10000000];
for (int i = 0; i < 10000000; i++) {
double a = (Math.random()*1000000);
z[i] = (int) a;
}
ImageProcessor ip = new ImageProcessor();
ip.imgRGBPercent(z);
}
public ImageProcessor() {
}
public void process(int[] x, int startPoint) {
(new Thread(new ReadThread(x, startPoint))).start();
}
public int[] imgRGBPercent(int[] x) {
ReadThread first = new ReadThread(x, 0);
ReadThread second = new ReadThread(x, 1);
ReadThread third = new ReadThread(x, 2);
ReadThread fourth = new ReadThread(x, 3);
Thread a = (new Thread(first));
Thread b = (new Thread(second));
Thread c = (new Thread(third));
Thread d = (new Thread(fourth));
long timeMetric = System.currentTimeMillis();
a.start();
b.start();
c.start();
d.start();
try {
a.join();
}
catch (Exception e) {
}
try {
b.join();
}
catch (Exception e) {
}
try {
c.join();
}
catch (Exception e) {
}
try {
d.join();
}
catch (Exception e) {
}
int redTotal, blueTotal, greenTotal;
redTotal = first.getRGBTotals()[0] + second.getRGBTotals()[0] + third.getRGBTotals()[0] + fourth.getRGBTotals()[0];
blueTotal = first.getRGBTotals()[1] + second.getRGBTotals()[1] + third.getRGBTotals()[1] + fourth.getRGBTotals()[1];
greenTotal = first.getRGBTotals()[2] + second.getRGBTotals()[2] + third.getRGBTotals()[2] + fourth.getRGBTotals()[2];
System.out.println(greenTotal);
System.out.println(System.currentTimeMillis() - timeMetric);
timeMetric = System.currentTimeMillis();
ColorValue cv1 = new ColorValue();
int sum = 0;
int sum1 = 0;
int sum2 = 0;
for (int i = 0; i < x.length; i++) {
sum += cv1.getGreen(x[i]);
sum1 += cv1.getRed(x[i]);
sum2 += cv1.getBlue(x[i]);
}
System.out.println(sum);
System.out.println(System.currentTimeMillis() - timeMetric);
int[] out = new int[3];
return out;
}
private class ReadThread implements Runnable {
private int[] colorArr;
private int startPoint, redTotal, blueTotal, greenTotal;
private ColorValue cv;
public ReadThread(int[] x, int startPoint) {
colorArr = x;
this.startPoint = startPoint;
cv = new ColorValue();
}
@Override
public void run() {
//System.out.println("hit");
for (int i = startPoint; i < colorArr.length; i+=4 ) {
redTotal += ColorValue.getRed(colorArr[i]);
blueTotal += ColorValue.getBlue(colorArr[i]);
greenTotal += ColorValue.getGreen(colorArr[i]);
}
}
public int[] getRGBTotals() {
int[] out = new int[3];
out[0] = redTotal;
out[1] = blueTotal;
out[2] = greenTotal;
return out;
}
}
}
导入java.awt.image.buffereImage;
导入java.lang.Thread;
公共类ImageProcessor扩展线程{
公共静态void main(字符串[]args){
int[]z=新int[10000000];
对于(int i=0;i<10000000;i++){
双a=(Math.random()*1000000);
z[i]=(int)a;
}
ImageProcessor ip=新的ImageProcessor();
ip.Imgrg百分之十(z);
}
公共图像处理器(){
}
公共作废流程(int[]x,int起始点){
(新线程(新的ReadThread(x,startPoint))).start();
}
公共整数[]imgRGBPercent(整数[]x){
readthreadfirst=新的ReadThread(x,0);
readthreadsecond=新的ReadThread(x,1);
ReadThread third=新的ReadThread(x,2);
ReadThread第四个=新的ReadThread(x,3);
线程a=(新线程(第一个));
线程b=(新线程(第二个));
线程c=(新线程(第三个));
线程d=(新线程(第四个));
长时间度量=System.currentTimeMillis();
a、 start();
b、 start();
c、 start();
d、 start();
试一试{
a、 join();
}
捕获(例外e){
}
试一试{
b、 join();
}
捕获(例外e){
}
试一试{
c、 join();
}
捕获(例外e){
}
试一试{
d、 join();
}
捕获(例外e){
}
int redTotal、blueTotal、greenTotal;
redTotal=first.getRGBTotals()[0]+second.getRGBTotals()[0]+third.getRGBTotals()[0]+third.getRGBTotals()[0];
blueTotal=first.getRGBTotals()[1]+second.getRGBTotals()[1]+third.getRGBTotals()[1]+third.getRGBTotals()[1];
greenTotal=first.getRGBTotals()[2]+second.getRGBTotals()[2]+third.getRGBTotals()[2]+third.getRGBTotals()[2];
系统输出打印项次(绿色总数);
System.out.println(System.currentTimeMillis()-timeMetric);
timeMetric=System.currentTimeMillis();
ColorValue cv1=新的ColorValue();
整数和=0;
int sum1=0;
int-sum2=0;
对于(int i=0;i
是。只要数据结构在读取时没有被修改,您就安全了。启动线程之前所做的每一次写入操作都会被启动的线程看到。是的,多个线程可以读取相同的对象,只要其他线程不同时修改它们就可以了。根据您正在执行的操作,可能会很有用,它会为您管理许多线程细节,因此值得研究。这个逻辑会让我有点担心:
for (int i = startPoint; i < colorArr.length; i+=4 ) {
redTotal += ColorValue.getRed(colorArr[i]);
blueTotal += ColorValue.getBlue(colorArr[i]);
greenTotal += ColorValue.getGreen(colorArr[i]);
}
但是,根据您的需要,您可能需要采取额外的步骤,以确保在整个循环运行时,程序的任何部分都不能在任何时候修改
colorArr
。然后,您需要开始查看锁定对象和<代码>同步< /代码>,并且您希望认真考虑为<代码> COLARARR < /代码>设置单独的类,通过使用synchronized
方法或包含逻辑的方法来修改和读取数组,以确保正确同步—通过将数组放入其自己的类中,所需的同步逻辑可以封装在该类中,因此该类的客户端不必担心它。这是您开始使用并发时需要考虑的事情。是的,它是线程安全的,因为您不需要在类的对象引用之间写入共享内存元素,只需要从中读取。注意:(1)import java.lang.thread
。从java.lang
中的所有内容都将自动导入。(2) 看起来您并不是真的希望ImageProcessor
扩展线程,因为您从未将其用作线程(在创建新的ImageProcessor
时,您不会覆盖run()
或提供Runnable
)。
for (int i = startPoint; i < colorArr.length; i+=4 ) {
int color = colorArr[i];
redTotal += ColorValue.getRed(color);
blueTotal += ColorValue.getBlue(color);
greenTotal += ColorValue.getGreen(color);
}