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 - Fatal编程技术网

Java 并发-条件同步方法

Java 并发-条件同步方法,java,multithreading,Java,Multithreading,我正在一行一行地同时阅读两个文本文件 我特别想做的是,当每个线程上的lineCount相同时,我想查看扫描仪当前读取的字符串 我环顾四周,寻找我可以实现的某种模式,但我无法理解它将如何帮助我实现我的目标。我是并发编程新手 到目前为止,我所做的是使用counterSync方法同步字符串读取和打印,我知道我已经在那里执行了线程锁定/暂停操作,并查看了字符串 public class concurrencyTest { public static void main(String[] args) t

我正在一行一行地同时阅读两个文本文件

我特别想做的是,当每个线程上的
lineCount
相同时,我想查看扫描仪当前读取的字符串

我环顾四周,寻找我可以实现的某种模式,但我无法理解它将如何帮助我实现我的目标。我是并发编程新手

到目前为止,我所做的是使用
counterSync
方法同步字符串读取和打印,我知道我已经在那里执行了线程锁定/暂停操作,并查看了字符串

public class concurrencyTest {

public static void main(String[] args) throws IOException {
        String filePath1 = "path1.txt";
        String filePath2 = "path2.txt";
        reader reader = new reader();
        MyThread source = new MyThread(reader, filePath1);
        MyThread target = new MyThread(reader, filePath2);

        source.start();
        target.start();
    }
    static public class reader {
        void read(String filePath) throws IOException {
            readFile(filePath);
        }
    }

    static synchronized void counterSync(String thread) {
        System.out.println(thread);
    }

    static class MyThread extends Thread {
        reader reader;
        String filePath;

        MyThread(reader reader, String filePath) {
            this.reader = reader;
            this.filePath = filePath;
        }

        @Override
        public void run() {
            try {
                reader.read(filePath);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    static void readFile(String filePath) throws IOException {
        FileInputStream inputStream = null;
        Scanner sc = null;
        int lineCount = 0;
        try {
            inputStream = new FileInputStream(filePath);
            sc = new Scanner(inputStream, "UTF-8");
            while (sc.hasNextLine()) {
                lineCount++;
                System.out.println(lineCount + "===" + sc.nextLine());
                counterSync(sc.nextLine());
            }
            if (sc.ioException() != null) {
                throw sc.ioException();
            }
        } finally {
            if (inputStream != null) {
                inputStream.close();
            }
            if (sc != null) {
                sc.close();
            }
        }
    }
}

似乎你没有发布一个完整的例子。但是,有几点一般性意见:

您可能可以对整数使用“比较和交换”逻辑,但不应期望它适用于更复杂的东西,如Java“字符串”或任何类型的容器

您只需使用语言中提供的同步对象即可。如果要更新甚至检查共享数据结构,必须持有正确的锁


当然,“线程安全队列”在许多设计中非常有用,因为它们促进了最常见的活动——消息传递——并允许各种线程以稍微不同的速度优雅地运行。您仍然需要锁定共享的任何内容,但尽管如此,这是一个非常有用的设计,与Unix®的“管道”一样古老。

您似乎没有发布完整的示例。但是,有几点一般性意见:

您可能可以对整数使用“比较和交换”逻辑,但不应期望它适用于更复杂的东西,如Java“字符串”或任何类型的容器

您只需使用语言中提供的同步对象即可。如果要更新甚至检查共享数据结构,必须持有正确的锁


当然,“线程安全队列”在许多设计中非常有用,因为它们促进了最常见的活动——消息传递——并允许各种线程以稍微不同的速度优雅地运行。您仍然需要锁定共享的任何内容,但尽管如此,这是一种非常有用的设计,与Unix®的“管道”一样古老。

好的,您需要的有点复杂,但仍然是可能的。
你的问题缺少一些例子,所以如果我在某些方面错了,请纠正我


您有两个线程:

  • 螺纹1
  • 螺纹2

和2个文件:

  • 文件1
  • 文件2
文件1的内容:

file1  
file2  
file3  
file4  
file5  
file6  
file7  
file8  
file9  
文件2的内容:

file11  
file22  
file33  
file44  
file55  
file66  
file77  
file88  
file99  

您希望停止相同行号上的所有线程,并对输出执行一些操作


这是读取文件的线程实现,我们将实例化它的2个实例,每个实例将管理一个文件

static class ReaderThread extends Thread {
    private File fileToRead;

    public final Object lock = new Object();
    private String currentLine;
    private AtomicInteger lineCount = new AtomicInteger(0);

    public ReaderThread(File fileToRead) {
        this.fileToRead = fileToRead;
    }

    @Override
    public void run() {
        synchronized (lock) {
            try {
                Stream<String> lines = Files.lines(Path.of(fileToRead.getPath()));
                lines.forEach(line -> {
                    currentLine = line;
                    // Here's your logic on different lines
                    if (lineCount.get() == 4 || lineCount.get() == 5 || lineCount.get() == 6) {
                        try {
                            lock.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    lineCount.getAndIncrement();
                });
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public String getCurrentLine() {
        return currentLine;
    }

    public boolean isLocked() {
        return getState().equals(State.WAITING);
    }
}

执行该程序将产生以下输出:


以下是完整的进口清单:

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Stream;  

请注意:这是一个粗鲁的例子,您需要正确地关闭线程进行管理,一些修饰符是公共的,所以要按照java指南封装它,正确地管理所有异常,并进行一些常规重构



如果您想要一个更通用的实现,以插入不同的线,以下应该是确定的:

static class HelperThread extends Thread {
    private List<ReaderThread> threads;

    @Override
    public void run() {
        while (true) {
            if (threads.stream().allMatch(ReaderThread::isLocked)) {
                System.out.println("next line:");

                threads.forEach(thread -> {
                    synchronized (thread.lock) {
                        System.out.println(thread.getCurrentLine());
                        thread.lock.notify();
                    }
                });

                System.out.println("\n");
            }
        }

    }

    public HelperThread(List<ReaderThread> threads) {
        this.threads = threads;
    }
}   
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Stream;

public class Main2 {

    public static void main(String[] args) {
        File f1 = new File(Objects.requireNonNull(Main2.class.getClassLoader().getResource("file1.txt")).getFile());
        File f2 = new File(Objects.requireNonNull(Main2.class.getClassLoader().getResource("file2.txt")).getFile());

        ReaderThread t1 = new ReaderThread(f1);
        ReaderThread t2 = new ReaderThread(f2);

        HelperThread helperThread = new HelperThread(List.of(t1, t2));

        helperThread.start();

        t1.setName("Reader1");
        t1.setName("Reader2");
        t1.start();
        t2.start();
    }

    static class ReaderThread extends Thread {
        private final File fileToRead;
        private final Object lock = new Object();
        private final AtomicInteger lineCount = new AtomicInteger(0);
        private String currentLine;

        public ReaderThread(File fileToRead) {
            this.fileToRead = fileToRead;
        }

        @Override
        public void run() {
            synchronized (lock) {
                try {
                    Stream<String> lines = Files.lines(Path.of(fileToRead.getPath()));
                    lines.forEach(line -> {
                        currentLine = line;
                        lineCount.getAndIncrement();
                    });
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        public void lock() throws InterruptedException {
            this.lock.wait();
        }

        public void unlock() {
            this.lock.notify();
        }

        public boolean isLocked() {
            return getState().equals(State.WAITING);
        }

        public Object getLock() {
            return lock;
        }

        public AtomicInteger getLineCount() {
            return lineCount;
        }

        public String getCurrentLine() {
            return currentLine;
        }

    }

    static class HelperThread extends Thread {
        private List<ReaderThread> threads;

        @Override
        public void run() {
            while (true) {
                threads.forEach(t -> {
                    try {
                        if (t.getName().equals("Reader1") && t.getLineCount().get() == 3) t.lock();
                        if (t.getName().equals("Reader2") && t.getLineCount().get() == 4) t.lock();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                });

                if (threads.stream().allMatch(ReaderThread::isLocked)) {
                    System.out.println("next line:");

                    threads.forEach(t -> {
                        synchronized (t.getLock()) {
                            System.out.println(t.getCurrentLine());
                            t.unlock();
                        }
                    });

                    System.out.println("\n");
                }
            }

        }

        public HelperThread(List<ReaderThread> threads) {
            this.threads = threads;
        }
    }

}
导入java.io.File;
导入java.io.IOException;
导入java.nio.file.Files;
导入java.nio.file.Path;
导入java.util.List;
导入java.util.Objects;
导入java.util.concurrent.AtomicInteger;
导入java.util.stream.stream;
公共类Main2{
公共静态void main(字符串[]args){
文件f1=新文件(Objects.requirennull(Main2.class.getClassLoader().getResource(“file1.txt”)).getFile());
文件f2=新文件(Objects.requirennull(Main2.class.getClassLoader().getResource(“file2.txt”)).getFile());
ReaderThread t1=新的ReaderThread(f1);
ReaderThread t2=新的ReaderThread(f2);
HelperThread HelperThread=新的HelperThread(List.of(t1,t2));
helperThread.start();
t1.设置名称(“读取器1”);
t1.设置名称(“读取器2”);
t1.start();
t2.start();
}
静态类ReaderThread扩展线程{
私有最终文件读取;
私有最终对象锁=新对象();
私有最终AtomicInteger lineCount=新的AtomicInteger(0);
专用字符串电流线;
公共读取器线程(文件或读取){
this.fileToRead=fileToRead;
}
@凌驾
公开募捐{
已同步(锁定){
试一试{
streamlines=Files.lines(Path.of(fileToRead.getPath());
行。forEach(行->{
currentLine=line;
lineCount.getAndIncrement();
});
}捕获(IOE异常){
e、 printStackTrace();
}
}
}
public void lock()引发InterruptedException{
这个。lock。wait();
}
公开作废解锁(){
this.lock.notify();
}
公共布尔值isLocked(){
返回getState().equals(State.WAITING);
}
公共对象getLock(){
返回锁;
}
公共原子整数getLineCount(){
返回行计数;
}
公共字符串getCurrentLine(){
回流线;
}
}
静态类HelperThread扩展线程{
私有列表线程;
@凌驾
公开募捐{
while(true){
threads.forEach(t->{
试一试{
如果(t.getName().equals(“Reader1”)和&t.getLineCount().get()==3)t.lock();
if(t.getName().eq
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Stream;  
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Stream;

public class Main2 {

    public static void main(String[] args) {
        File f1 = new File(Objects.requireNonNull(Main2.class.getClassLoader().getResource("file1.txt")).getFile());
        File f2 = new File(Objects.requireNonNull(Main2.class.getClassLoader().getResource("file2.txt")).getFile());

        ReaderThread t1 = new ReaderThread(f1);
        ReaderThread t2 = new ReaderThread(f2);

        HelperThread helperThread = new HelperThread(List.of(t1, t2));

        helperThread.start();

        t1.setName("Reader1");
        t1.setName("Reader2");
        t1.start();
        t2.start();
    }

    static class ReaderThread extends Thread {
        private final File fileToRead;
        private final Object lock = new Object();
        private final AtomicInteger lineCount = new AtomicInteger(0);
        private String currentLine;

        public ReaderThread(File fileToRead) {
            this.fileToRead = fileToRead;
        }

        @Override
        public void run() {
            synchronized (lock) {
                try {
                    Stream<String> lines = Files.lines(Path.of(fileToRead.getPath()));
                    lines.forEach(line -> {
                        currentLine = line;
                        lineCount.getAndIncrement();
                    });
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        public void lock() throws InterruptedException {
            this.lock.wait();
        }

        public void unlock() {
            this.lock.notify();
        }

        public boolean isLocked() {
            return getState().equals(State.WAITING);
        }

        public Object getLock() {
            return lock;
        }

        public AtomicInteger getLineCount() {
            return lineCount;
        }

        public String getCurrentLine() {
            return currentLine;
        }

    }

    static class HelperThread extends Thread {
        private List<ReaderThread> threads;

        @Override
        public void run() {
            while (true) {
                threads.forEach(t -> {
                    try {
                        if (t.getName().equals("Reader1") && t.getLineCount().get() == 3) t.lock();
                        if (t.getName().equals("Reader2") && t.getLineCount().get() == 4) t.lock();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                });

                if (threads.stream().allMatch(ReaderThread::isLocked)) {
                    System.out.println("next line:");

                    threads.forEach(t -> {
                        synchronized (t.getLock()) {
                            System.out.println(t.getCurrentLine());
                            t.unlock();
                        }
                    });

                    System.out.println("\n");
                }
            }

        }

        public HelperThread(List<ReaderThread> threads) {
            this.threads = threads;
        }
    }

}
public static void main(String[] args) throws IOException {
    String filePath1 = "path1.txt";
    String filePath2 = "path2.txt";

    ReaderThread reader1 = new ReaderThread(filePath1);
    ReaderThread reader2 = new ReaderThread(filePath2);

    CyclicBarrier cyclicBarrier = new CyclicBarrier(2, () -> {
        //processing when condition met in both thread
        List<String> lines1 = reader1.getLines();
        List<String> lines2 = reader2.getLines();
        System.out.println(lines1.get(lines1.size() - 1) + " " + lines2.get(lines2.size()-1));
    });


    reader1.setCyclicBarrier(cyclicBarrier);
    reader2.setCyclicBarrier(cyclicBarrier);

   reader1.start();
   reader2.start();
}


public static class ReaderThread extends Thread {
    CyclicBarrier cyclicBarrier;
    String file;
    List<String> lines = new ArrayList<>();
    public void setCyclicBarrier(CyclicBarrier cyclicBarrier) {
        this.cyclicBarrier = cyclicBarrier;
    }
    public ReaderThread(String file) {
        this.file = file;
    }
    @Override
    public void run() {
        try (BufferedReader reader = Files.newBufferedReader(Paths.get(file))) {
            String line = null;
            for (int i = 0; (line = reader.readLine()) != null; i++) {
                lines.add(line);
                //condition do something
                if (i % 10 == 0) {
                    cyclicBarrier.await();
                }
            }
        } catch (IOException | InterruptedException | BrokenBarrierException e) {
            e.printStackTrace();
        }
    }
    public List<String> getLines() {
        return new ArrayList<>(lines);
    }
}
this is from file1 1232123321312 this is from file 2 1232123321312
this is from file1 1232123321312 this is from file 2 1232123321312
this is from file1 1232123321312 this is from file 2 1232123321312