Java 线程并发问题
我有一个简单的代码,由4个线程组成(2个修改数据,2个读取数据)。我只是编写了这个示例代码来处理信号量,我不知道为什么会出现ava.base/java.util.ArrayList$Itr.checkForComodification异常?以下是源代码,感谢您提供的任何见解Java 线程并发问题,java,Java,我有一个简单的代码,由4个线程组成(2个修改数据,2个读取数据)。我只是编写了这个示例代码来处理信号量,我不知道为什么会出现ava.base/java.util.ArrayList$Itr.checkForComodification异常?以下是源代码,感谢您提供的任何见解 import java.util.ArrayList; import java.util.List; import java.util.concurrent.Semaphore; public class Semaphor
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Semaphore;
public class SemaphoreExample {
public static class InnerWriterSemaphoreThread implements Runnable {
private final List<String> fList;
private final Semaphore fWriteSem;
InnerWriterSemaphoreThread(List<String> list, Semaphore w) {
fList = list;
fWriteSem = w;
}
private void prune() {
System.out.println(Thread.currentThread().getName()+" in prune()..");
for (String s : fList) {
fList.remove(s);
}
}
@Override
public void run() {
String name = Thread.currentThread().getName();
String text;
while (true) {
text = RandomTextGenerator.getRandomSNumbertring();
try {
while(!fWriteSem.tryAcquire()){
System.out.println(name+" waiting to accquire semaphore to write..");
Thread.sleep(0L,4);
}
if (fList.size() > 10) {
prune();
}
fList.add(text);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
fWriteSem.release();// notify readers that write has completed
System.out.println(name+" finished writing, releasing semaphore..");
}
}//while()
}//run()
}//WriterSemaphoreThread
public static class InnerReaderSemaphoreThread implements Runnable {
private final List<String> fList;
private final Semaphore fWriteSem;
InnerReaderSemaphoreThread(List<String> list,Semaphore w) {
fList = list;
fWriteSem = w;
}
private void sleep(){
try{
Thread.sleep(0L, 4);
}catch(InterruptedException e){
e.printStackTrace();
}
}
@Override
public void run() {
String name = Thread.currentThread().getName();
while (true) {
System.out.println(name + " in run()..");
try {
while(fList.isEmpty()){
System.out.println(name+" list is empty, going to sleep..");
sleep();
}
while(!fWriteSem.tryAcquire()){
System.out.println(name+" waiting to accquire semaphor to read..");
Thread.sleep(0l,4);
}
for (String text : fList) {
System.out.println(name + " reading from list " + text);
}
}catch (InterruptedException e) {
e.printStackTrace();
}
finally{
fWriteSem.release(); //Notify threads who want to write to the list
System.out.println(name+" finished reading, releasing semaphore and going to sleep..");
sleep();
}
}
}
}//ReaderSemaphoreThread
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
List<String> list = new ArrayList<>();
Semaphore r = new Semaphore(1);
Thread th1 = new Thread(new InnerWriterSemaphoreThread(list, r), "Thread 1");
Thread th2 = new Thread(new InnerReaderSemaphoreThread(list, r), "Thread 2");
Thread th3 = new Thread(new InnerWriterSemaphoreThread(list, r), "Thread 3");
Thread th4 = new Thread(new InnerReaderSemaphoreThread(list, r), "Thread 4");
th2.start();
th4.start();
th1.start();
th3.start();
}
}
import java.util.ArrayList;
导入java.util.List;
导入java.util.concurrent.Semaphore;
公共类信号量示例{
公共静态类InnerWriterSemaphoreThread实现可运行{
私人最终名单;
私有最终信号量fWriteSem;
InnerWriterSemaphoreThread(列表,信号量w){
fList=列表;
fWriteSem=w;
}
私有空剪枝(){
System.out.println(Thread.currentThread().getName()+“in prune()”);
for(字符串s:fList){
移走(s);;
}
}
@凌驾
公开募捐{
字符串名称=Thread.currentThread().getName();
字符串文本;
while(true){
text=RandomTextGenerator.getRandomSNumbertring();
试一试{
而(!fWriteSem.tryAcquire()){
System.out.println(name+“等待接收信号量写入…”);
线程。睡眠(0升,4);
}
如果(fList.size()>10){
修剪();
}
fList.add(文本);
}捕捉(中断异常e){
e、 printStackTrace();
}最后{
fWriteSem.release();//通知读卡器写入已完成
System.out.println(name+“完成写入,释放信号量…”);
}
}//while()
}//运行()
}//WriterSemaphoreThread
公共静态类InnerReaderSemaphoreThread实现可运行{
私人最终名单;
私有最终信号量fWriteSem;
InnerReaderSemaphoreThread(列表,信号量w){
fList=列表;
fWriteSem=w;
}
私人虚空睡眠(){
试一试{
线程。睡眠(0升,4);
}捕捉(中断异常e){
e、 printStackTrace();
}
}
@凌驾
公开募捐{
字符串名称=Thread.currentThread().getName();
while(true){
System.out.println(name+“in run()”);
试一试{
while(fList.isEmpty()){
System.out.println(name+“列表为空,正在休眠…”);
睡眠();
}
而(!fWriteSem.tryAcquire()){
System.out.println(name+“等待获取信号量读取…”);
线程。睡眠(0升,4);
}
for(字符串文本:fList){
System.out.println(名称+“从列表中读取”+文本);
}
}捕捉(中断异常e){
e、 printStackTrace();
}
最后{
fWriteSem.release();//通知要写入列表的线程
System.out.println(name+“已完成读取、释放信号量并进入睡眠状态…”);
睡眠();
}
}
}
}//读卡器读卡器
/**
*@param指定命令行参数
*/
公共静态void main(字符串[]args){
列表=新的ArrayList();
信号量r=新信号量(1);
Thread th1=新线程(新的innerWritersMaphorethread(列表,r),“Thread 1”);
Thread th2=新线程(新的InnerReaderSemaphoreThread(列表,r),“Thread 2”);
Thread th3=新线程(新的innerWritersMaphorethread(列表,r),“Thread 3”);
Thread th4=新线程(新的内部读取器emaphorethread(列表,r),“Thread 4”);
th2.start();
th4.start();
th1.start();
th3.start();
}
}
上面是注释中提到的@assylas的示例源代码,当您从foreach循环的列表中删除元素时,会发生这种情况。替换
for (String s : fList) {
fList.remove(s);
}
与
正如注释中提到的@assylas,当您从foreach循环的列表中删除元素时,就会发生这种情况。替换
for (String s : fList) {
fList.remove(s);
}
与
点击你问题下方的编辑链接(此评论上方)并添加你的代码。嗨,我编辑了帖子,添加了评论,当我试图添加源代码时,它说你的帖子只有代码,请添加一些评论。回到原点:-)除了解释错误之外,您还需要提供一些示例代码。如果您在for each循环中修改ArrayList,则可能会发生异常。我终于在源代码末尾添加了一行文本,并接受了它。我希望源代码清晰易读。单击问题下方的编辑链接(此注释上方)并添加代码。您好,我编辑了帖子,添加了注释,当我尝试添加源代码时,它显示您的帖子只有代码,请添加一些注释。回到原点:-)除了解释错误之外,您还需要提供一些示例代码。如果您在for each循环中修改ArrayList,则可能会发生异常。我终于在源代码末尾添加了一行文本,并接受了它。我希望源代码清晰易读。@assylias:谢谢您的洞察力。这正是我在查看堆栈跟踪时抛出异常的地方,在过去的两天里我完全感到困惑。对于我来说,为什么抛出这个异常仍然是一个两难的问题?共享信号量只有一个许可证,所有线程在读取或修改列表之前等待获取共享信号量,只有一个线程成功,因此只有一个线程正在写入和修剪列表。我有一个使用ReadWriteLock的不同版本的代码,它工作得很好,但我的目标是根据java文档测试信号量的功能。这不是线程问题。您试图从循环中的列表中删除项。所以,如果您在单线程中调用它,可能会引发这样的异常app@assylias:Th