Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/375.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
Java 线程并发问题_Java - Fatal编程技术网

Java 线程并发问题

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

我有一个简单的代码,由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 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