gpt4 book ai didi

Java多线程代码给出错误-Illegal Monitor Exception

转载 作者:行者123 更新时间:2023-12-01 08:47:42 28 4
gpt4 key购买 nike

我正在尝试最近学到的一些多线程概念,但无法运行它。

它给出了 IllegalMonitorStateException 但没有弄清楚错误发生的原因。

因此,关于代码2线程引用名称填充器和写入器都共享一个数组列表,填充器正在用整数填充数组列表(但最多填充30个),并且在填充器和写入器线程添加每个数字后读取数组列表获取该项目将其写入文件将其从数组列表中删除。为了更好地理解,在代码中添加了注释。

package com.utsav.pratice;

import java.io.*;
import java.util.ArrayList;

public class Main {

public static void main(String[] args) throws FileNotFoundException {
//shared arraylist-synchronized
ArrayList<Integer> integerArrayList = new ArrayList<>();
//writter will write to this file numbers added to arraylist by filler and than will remove it from arraylist
FileOutputStream file = new FileOutputStream("Numbers.txt");
//filler will mark it true after completing all numbers
final boolean[] numbersCompleted = {false};

Thread filler=new Thread(new Runnable(){
@Override
public void run(){
//1-30 numbers one by one will be written to Arraylist
for (int i = 1; i < 31; i++) {
synchronized (integerArrayList) {
//if arraylist is not empty that means writter not performed on arraylist hence invoking wait to release lock so writter could perform
while(!integerArrayList.isEmpty()){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//so arraylist is empty now lets fill it,notify that releasing lock and than put thread to sleep
integerArrayList.add(i);
System.out.println("Number added");
if(i==30){
numbersCompleted[0] =true;}
notifyAll();
}
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Numbers adding completed");
}
});

Thread writter=new Thread(new Runnable(){
@Override
public void run(){
//if numbers are completed than nothing to write come out of loop
while(!numbersCompleted[0]) {
synchronized (integerArrayList) {
//if arraylist is empty than its time for filler to work hence putting thread to wait so lock could be released for filler
while (integerArrayList.isEmpty()){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//so arraylist is not empty now lets write it & than remove it from arraylist,notify that releasing lock and than put thread to sleep
try (DataOutputStream fileWritter = new DataOutputStream(new BufferedOutputStream(file));) {
fileWritter.writeInt(integerArrayList.get(0));
System.out.println("Random number written");
} catch (IOException e) {
e.printStackTrace();
}
integerArrayList.remove(0);
notifyAll();
}
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("File written completely");
}
});

//starting both threads-2cases filler takes the key-ok(will fill & wait) or filler takes the key(will wait since will be empty)
writter.start();
filler.start();

最佳答案

这里:

synchronized (integerArrayList) 

您正在列表上进行同步。

但是您正在等待/通知您的匿名线程对象的this!作为 javadoc 中的第一个信息说:

抛出该异常表示线程尝试在对象的监视器上等待,或通知在不拥有指定监视器的情况下在对象的监视器上等待的其他线程。

所以当你将它们更改为

时,事情应该会起作用
integerArrayList.wait()

例如(所有使用 wait/notify/...)!

并提示:不要做类似的事情

final ArrayList<Integer> integerArrayList = new ArrayList<>();

只是去

List<Integer> numbers = new ArrayList<>();

简单地使用具体的 impl 类类型作为变量的类型;而且也不作为其名称的一部分!

关于Java多线程代码给出错误-Illegal Monitor Exception,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42573841/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com