在java中以循环方式运行线程
我不熟悉java中的多线程和同步。我试图实现一个任务,其中我有5个文件,每个文件将由一个特定的线程读取。每个线程应该从文件中读取一行,然后将执行转发到下一个线程,以此类推。当所有5个线程都读取第一行时,再次从运行文件1的第2行的线程1开始,依此类推在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
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
互操作,以及这些方法的精确语义。关于本主题将是一个很好的开始。虽然这不是使用多线程的理想方案,但由于这是一个任务,我提出了一个可行的解决方案。线程将按顺序执行,并且没有几点需要注意:
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.
}
}