Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/334.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
“线程中的异常”;螺纹-2“;代码中的java.lang.NullPointerException.error_Java_Arrays_Multithreading_Locking - Fatal编程技术网

“线程中的异常”;螺纹-2“;代码中的java.lang.NullPointerException.error

“线程中的异常”;螺纹-2“;代码中的java.lang.NullPointerException.error,java,arrays,multithreading,locking,Java,Arrays,Multithreading,Locking,我的代码运行正常(至少有点正常),我一定做了一些更改,因为现在它甚至无法启动。代码中没有显示错误,但当我尝试运行它时,会显示以下内容: Exception in thread "Thread-2" java.lang.NullPointerException at azsystem3.Add.run(Main.java:57) at java.lang.Thread.run(Thread.java:662) (Main.java:57)是这一行:sum.s+=a

我的代码运行正常(至少有点正常),我一定做了一些更改,因为现在它甚至无法启动。代码中没有显示错误,但当我尝试运行它时,会显示以下内容:

Exception in thread "Thread-2" java.lang.NullPointerException
        at azsystem3.Add.run(Main.java:57)
        at java.lang.Thread.run(Thread.java:662)
(Main.java:57)是这一行:
sum.s+=a[i]
我怎么修理它?
这是我的相关代码:

package azsystem3;

import java.util.*;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

class Fill implements Runnable{

    int []a;
    static Random b = new Random();
    int start;
    int end;
    public Fill(int[]a,int start,int end){
        this.a=a;
        this.start=start;
        this.end=end;
    }
    public void run(){

        for(int i=this.start;i<this.end;i++){
            a[i]=b.nextInt(100);

        }
    }
}
class value{
    int s;
}


class Add implements Runnable{
    value sum;
    Lock L ;
    int[]a;
    int start;
    int end;

    //public long  sum=0;
    public Add(int[]a,int start, int end,Lock L,value s){

        this.L=L;
        this.start=start;
        this.end=end;
        sum=s;

    }

    public void run(){
        int i;
        for( i=start;i<end;i++)
            L.lock();
            sum.s+=a[i];
            L.unlock();

    }
}
 class main {


    public static void main(String[] args) {

        value sum=new value();
        Lock Lock=new ReentrantLock();
        int[] array = new int[100000];

        Scanner sc=new Scanner (System.in);
        System.out.println ("Enter number : ");
        int n = sc.nextInt();
        int tmp = 100000 / n;
        Thread[] t = new Thread[n];
        for (int i = 0; i < n; i++) {
            t[i] = new Thread(new Fill(array, (i) * tmp, (i + 1) * tmp));
            t[i].start();
        }

        for (int i = 0; i < n; i++) {
            try {
                t[i].join();
            } catch (InterruptedException exception) {
            }
        }
        Thread[] t1 = new Thread[n];
        Add[] add = new Add[n];
        long start = System.currentTimeMillis();
        for (int i = 0; i < n; i++) {
            add[i] = new Add(array, (i) * tmp, (i + 1) * tmp,Lock,sum);
            t1[i] = new Thread(add[i]);
            t1[i].start();
        }

        for (int i = 0; i < n; i++) {
            try {
                t1[i].join();
            } catch (InterruptedException exception) {
            }
        }
        long end = System.currentTimeMillis();

        System.out.println("sum : " + sum);
        System.out.println("time : " + (end - start) + "ms");



        }
    }
包azsystem3;
导入java.util.*;
导入java.util.concurrent.locks.Lock;
导入java.util.concurrent.locks.ReentrantLock;
类填充实现可运行{
int[]a;
静态随机b=新随机();
int启动;
内端;
公共填充(int[]a,int开始,int结束){
这个a=a;
这个。开始=开始;
这个。结束=结束;
}
公开募捐{

对于(int i=this.start;i线程安全性不仅需要在
run()上锁定
-方法,但您也应该让类的私有成员
添加
,尤其是
sum
成员,final。否则线程可能会看到类型为
value
的未完全初始化对象,其中
sum
-成员仍然
为null

注意:为了更好的可读性,请尝试遵循标准Java代码约定

另一个观察,这个代码

for( i=start;i<end;i++) // missing opening bracket {
    L.lock();
    sum.s+=a[i];
    L.unlock(); // missing closing bracket }

for(i=start;i虽然这看起来像是线程安全问题,但出现
NullPointerException
的原因很简单:

Add
类的构造函数中,您忘记分配
int
数组实例变量
a
,即缺少一个简单的
this.a=a;

这就是为什么您应该尽可能将每个实例变量声明为
final
。然后编译器会告诉您每个缺少的值赋值



当然,您必须修复
Add.run()中缺少的大括号
方法,否则您将得到一个死锁。在您的情况下,只有第一个线程抛出了
NullPointerException
,而所有其他线程一直在等待。

@Honey使类的所有成员
添加
最终,并且不要忘记for循环缺少的括号。抱歉,我犯了一个错误;-)如前所述,您必须插入缺少的大括号。但要修复
NullPointerException
,您必须将
this.a=a;
插入构造函数中。这是一个很好的捕获方法。a=a;
一个主要问题是呈现的代码可读性差,因此乍一看这些东西很容易被忽略。使用更好的编码风格会更好更少的错误!是的。良好的编码风格不应该被低估。
for( i=start;i<end;i++) {
  L.lock();
}

sum.s+=a[i];
L.unlock();