Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.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_Multithreading_Synchronization - Fatal编程技术网

在java中以循环方式运行线程

在java中以循环方式运行线程,java,multithreading,synchronization,Java,Multithreading,Synchronization,我不熟悉java中的多线程和同步。我试图实现一个任务,其中我有5个文件,每个文件将由一个特定的线程读取。每个线程应该从文件中读取一行,然后将执行转发到下一个线程,以此类推。当所有5个线程都读取第一行时,再次从运行文件1的第2行的线程1开始,依此类推 Thread ReadThread1 = new Thread(new ReadFile(0)); Thread ReadThread2 = new Thread(new ReadFile(1)); Thread ReadTh

我不熟悉java中的多线程和同步。我试图实现一个任务,其中我有5个文件,每个文件将由一个特定的线程读取。每个线程应该从文件中读取一行,然后将执行转发到下一个线程,以此类推。当所有5个线程都读取第一行时,再次从运行文件1的第2行的线程1开始,依此类推

    Thread ReadThread1 = new Thread(new ReadFile(0));
    Thread ReadThread2 = new Thread(new ReadFile(1));
    Thread ReadThread3 = new Thread(new ReadFile(2));
    Thread ReadThread4 = new Thread(new ReadFile(3));
    Thread ReadThread5 = new Thread(new ReadFile(4));

    // starting all the threads
    ReadThread1.start();
    ReadThread2.start();
    ReadThread3.start();
    ReadThread4.start();
    ReadThread5.start();
在ReadFile(实现Runnable)中,在run方法中,我尝试在bufferreader对象上进行同步

        BufferedReader br = null;

            String sCurrentLine;
            String filename="Source/"+files[fileno];
            br = new BufferedReader(new FileReader(filename));

            synchronized(br)
            {

            while ((sCurrentLine = br.readLine()) != null) {
                int f=fileno+1;
                System.out.print("File No."+f);
                System.out.println("-->"+sCurrentLine);
br.notifyAll();
// some thing needs to be dine here i guess 
}}

需要帮助

您缺少拼图的许多部分:

  • 您试图在每个线程的本地对象上进行同步。这可能没有效果,JVM甚至可能会删除整个锁定操作

  • 执行
    notifyAll
    ,但没有匹配的
    wait

  • 缺少的
    wait
    必须位于
    run
    方法的顶部,而不是如您所示的底部


总之,我担心此时修复代码超出了StackOverflow的回答范围。我的建议是首先熟悉核心概念:Java中锁的语义,它们如何与
wait
notify
互操作,以及这些方法的精确语义。关于这个主题将是一个很好的开始。

你错过了谜题的许多部分:

  • 您试图在每个线程的本地对象上进行同步。这可能没有效果,JVM甚至可能会删除整个锁定操作

  • 执行
    notifyAll
    ,但没有匹配的
    wait

  • 缺少的
    wait
    必须位于
    run
    方法的顶部,而不是如您所示的底部


总之,我担心此时修复代码超出了StackOverflow的回答范围。我的建议是首先熟悉核心概念:Java中锁的语义,它们如何与
wait
notify
互操作,以及这些方法的精确语义。关于本主题将是一个很好的开始。

虽然这不是使用多线程的理想方案,但由于这是一个任务,我提出了一个可行的解决方案。线程将按顺序执行,并且没有几点需要注意:

  • 当前线程无法向前移动以读取文件中的行,除非其上一个线程按照循环方式读取,否则当前线程无法向前移动以读取文件中的行
  • 当前线程读取完该行后,它必须通知另一个线程,否则该线程将永远等待
  • 我已经用temp包中的一些文件测试了这段代码,它能够以循环方式读取行。我相信Phaser也可以用来解决这个问题

        public class FileReaderRoundRobinNew {
            public Object[] locks;
    
            private static class LinePrinterJob implements Runnable {
                private final Object currentLock;
    
    
    private final Object nextLock;
            BufferedReader bufferedReader = null;
    
            public LinePrinterJob(String fileToRead, Object currentLock, Object nextLock) {
                this.currentLock = currentLock;
                this.nextLock = nextLock;
                try {
                    this.bufferedReader = new BufferedReader(new FileReader(fileToRead));
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                }
            }
    
            @Override
            public void run() {
                /*
                 * Few points to be noted:
                 * 1. Current thread cannot move ahead to read the line in the file until and unless its immediately previous thread is done as they are supposed to read in round-robin fashion.
                 * 2. After current thread is done reading the line it must notify the other thread else that thread will wait forever.
                 * */
                String currentLine;
                synchronized(currentLock) {
                    try {
                        while ( (currentLine = bufferedReader.readLine()) != null) {
                            try {
                                currentLock.wait();
                                System.out.println(currentLine);
                            }
                            catch(InterruptedException e) {}
                            synchronized(nextLock) {
                                nextLock.notify();
                            }
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                synchronized(nextLock) {
                    nextLock.notify(); /// Ensures all threads exit at the end
                }
            }
        }
    
        public FileReaderRoundRobinNew(int numberOfFilesToRead) {
            locks = new Object[numberOfFilesToRead];
            int i;
            String fileLocation = "src/temp/";
            //Initialize lock instances in array.
            for(i = 0; i < numberOfFilesToRead; ++i) locks[i] = new Object();
            //Create threads
            int j;
            for(j=0; j<(numberOfFilesToRead-1); j++ ){
                Thread linePrinterThread = new Thread(new LinePrinterJob(fileLocation + "Temp" + j,locks[j],locks[j+1]));
                linePrinterThread.start();
            }
            Thread lastLinePrinterThread = new Thread(new LinePrinterJob(fileLocation + "Temp" + j,locks[numberOfFilesToRead-1],locks[0]));
            lastLinePrinterThread.start();
        }
    
        public void startPrinting() {
            synchronized (locks[0]) {
                locks[0].notify();
            }
        }
    
        public static void main(String[] args) {
            FileReaderRoundRobinNew fileReaderRoundRobin = new FileReaderRoundRobinNew(4);
            fileReaderRoundRobin.startPrinting();
        }
    }
    
    公共类文件ReaderRobinNew{
    公共对象[]锁;
    私有静态类LinePrinterJob实现Runnable{
    私有最终对象currentLock;
    私有最终对象nextLock;
    BufferedReader BufferedReader=null;
    公共LinePrinterJob(字符串文件读取、对象currentLock、对象nextLock){
    this.currentLock=currentLock;
    this.nextLock=nextLock;
    试一试{
    this.bufferedReader=new bufferedReader(new FileReader(fileToRead));
    }catch(filenotfounde异常){
    e、 printStackTrace();
    }
    }
    @凌驾
    公开募捐{
    /*
    *需要注意的几点:
    *1.当前线程无法向前移动以读取文件中的行,除非其上一个线程按照循环方式读取,否则当前线程无法向前移动以读取文件中的行。
    *2.当前线程读取完该行后,必须通知另一个线程,否则该线程将永远等待。
    * */
    串电流线;
    已同步(当前锁定){
    试一试{
    而((currentLine=bufferedReader.readLine())!=null){
    试一试{
    currentLock.wait();
    系统输出打印项次(当前行);
    }
    捕获(中断异常e){}
    已同步(nextLock){
    nextLock.notify();
    }
    }
    }捕获(IOE异常){
    e、 printStackTrace();
    }
    }
    已同步(nextLock){
    nextLock.notify();///确保所有线程都在末尾退出
    }
    }
    }
    公共文件ReaderRobinNew(文件存储的整数){
    locks=新对象[NumberOfFileStored];
    int i;
    字符串fileLocation=“src/temp/”;
    //初始化数组中的锁实例。
    对于(i=0;i
    上述示例可以根据具体要求进行修改。此处FileReaderRobinusingPhaser的构造函数考虑了文件的数量和从每个文件中读取的行数。还需要考虑边界条件<
    public class FileReaderRoundRobinUsingPhaser {
    
        final List<Runnable> tasks = new ArrayList<>();
        final int numberOfLinesToRead;
    
        private static class LinePrinterJob implements Runnable {
            private BufferedReader bufferedReader;
    
            public LinePrinterJob(BufferedReader bufferedReader) {
                this.bufferedReader = bufferedReader;
            }
    
            @Override
            public void run() {
                String currentLine;
                try {
                    currentLine = bufferedReader.readLine();
                    System.out.println(currentLine);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    
        public FileReaderRoundRobinUsingPhaser(int numberOfFilesToRead, int numberOfLinesToRead) {
            this.numberOfLinesToRead = numberOfLinesToRead;
            String fileLocation = "src/temp/";
            for(int j=0; j<(numberOfFilesToRead-1); j++ ){
                try {
                    tasks.add(new LinePrinterJob(new BufferedReader(new FileReader(fileLocation + "Temp" + j))));
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                }
            }
        }
    
        public void startPrinting( ) {
            final Phaser phaser = new Phaser(1){
                @Override
                protected boolean onAdvance(int phase, int registeredParties) {
                    System.out.println("Phase Number: " + phase +" Registeres parties: " + getRegisteredParties() + " Arrived: " + getArrivedParties());
                    return ( phase >= numberOfLinesToRead || registeredParties == 0);
                }
            };
    
            for(Runnable task : tasks) {
                phaser.register();
                new Thread(() -> {
                    do {
                        phaser.arriveAndAwaitAdvance();
                        task.run();
                    } while(!phaser.isTerminated());
                }).start();
            }
            phaser.arriveAndDeregister();
        }
    
        public static void main(String[] args) {
            FileReaderRoundRobinUsingPhaser fileReaderRoundRobin = new FileReaderRoundRobinUsingPhaser(4, 4);
            fileReaderRoundRobin.startPrinting();
            // Files will be accessed in round robin fashion but not exactly in same order always. For example it can read 4 files as 1234 then 1342 or 1243 etc.
        }
    
    }