【发布时间】:2018-05-11 09:03:17
【问题描述】:
我的任务:我需要在多个线程中生成矩阵的 BASE(数组)。线程可能根本不会生成矩阵,所以我尝试限制每个线程的生命周期。
我的想法:我制作了包含我的矩阵生成任务的 volatile 数组,并制作了包含线程和信息类的ConcurrentHashMap(任务数组中的索引和线程创建时间)
我的问题:当我尝试处理数组时,我得到了NullPointerException
线程信息类:
public class ThreadInformation {
private long timeCreated;
private int automatIndex;
public ThreadInformation (long timeCreated, int automatIndex) {
this.timeCreated = timeCreated;
this.automatIndex = automatIndex;
}
public long getTimeCreated() {
return timeCreated;
}
public int getIndex() {
return automatIndex;
}
}
多线程类:
public class MultiTaskGenerator {
private final int BASE_SIZE = 10;
private final Automat[] BASE = new Automat[BASE_SIZE];
private static final int THREAD_COUNT = 8;
private final int THREAD_LIVE_TIME_SEC = 10;
private Map<Thread, ThreadInformation> threads = new ConcurrentHashMap<>();
private volatile GeneratorTask[] tasks = new GeneratorTask[THREAD_COUNT];
private int automatReady = 0;
MultiTaskGenerator() {
getThreadResult();
}
private void initThreads() {
for (int i = 0; i < THREAD_COUNT; i++) {
int j = i;
System.out.println("Thread №" + j + " started");
threads.put(new Thread(() -> {
tasks[j] = new GeneratorTask();
}), new ThreadInformation(System.currentTimeMillis(), j));
}
startThreads();
}
private void initNewThread(int index) {
for (int i = 0; i < tasks.length; i++) {
if (i == index) {
threads.put(new Thread(() -> {
tasks[index] = new GeneratorTask();
}), new ThreadInformation(System.currentTimeMillis(), index));
}
}
}
private void startThreads() {
for (Thread thread : threads.keySet()) {
Thread.State state = thread.getState();
if (state == Thread.State.NEW) {
thread.start();
}
}
}
private void getThreadResult() {
initThreads();
for (int i = 0; i < tasks.length; i++) {
System.out.println(tasks[i]);
}
while (automatReady < BASE_SIZE) {
Set mapSet = threads.entrySet();
Iterator iterator = mapSet.iterator();
while (iterator.hasNext()) {
Map.Entry<Thread, ThreadInformation> mapEntry = (Map.Entry)iterator.next();
if (!mapEntry.getKey().isAlive()) {
if (automatReady == BASE_SIZE) continue;
int currentIndex = mapEntry.getValue().getIndex();
BASE[automatReady] = tasks[currentIndex].getAutomat();
System.out.println("Добавлен автомат № " + automatReady);
automatReady++;
System.out.println("Thread №" + mapEntry.getValue().getIndex() + " finished successfully");
iterator.remove();
initNewThread(mapEntry.getValue().getIndex());
startThreads();
System.out.println("Thread №" + mapEntry.getValue().getIndex() + " started");
} else {
if ((System.currentTimeMillis() - mapEntry.getValue().getTimeCreated()) < (THREAD_LIVE_TIME_SEC * 1000)) continue;
int taskIndex = mapEntry.getValue().getIndex();
tasks[taskIndex].stopGeneration(true);
System.out.println("Thread №" + taskIndex + " stoped");
mapEntry.getKey().interrupt();
iterator.remove();
System.out.println("Thread №" + taskIndex + " started");
initNewThread(mapEntry.getValue().getIndex());
startThreads();
}
}
}
threads.clear();
}
public Automat[] getBASE() {
return BASE;
}
}
堆栈跟踪:
Thread №0 started
Thread №1 started
Thread №2 started
Thread №3 started
Thread №4 started
Thread №5 started
Thread №6 started
Thread №7 started
null
null
null
null
null
null
null
null
Exception in thread "main" java.lang.NullPointerException
at ru.stsz.MultiTaskGenerator.getThreadResult(MultiTaskGenerator.java:78)
at ru.stsz.MultiTaskGenerator.<init>(MultiTaskGenerator.java:19)
at ru.stsz.MainApp.main(MainApp.java:6)
谁能给我建议如何解决这个问题?
【问题讨论】:
-
请发布堆栈跟踪错误以获得帮助。
-
使用
volatile关键字只能保证原始字段、对象引用或不可变对象引用的字段的安全发布。数组不是上面列出的。 -
@Lorelorelore 我添加了堆栈跟踪。
-
您在单独的线程中设置了
tasks的值,但您尝试在主线程中立即访问tasks。您的代码中没有等待线程完成的任何内容,因此无法确保tasks已正确初始化。 -
@MaxVollmer 那么我应该为什么更改数组?我现在不使用 getBase() 因为我无法填充基础。我只是在 main 中调用 new MultiTaskGenerator()
标签: java arrays multithreading nullpointerexception