在Java中使用多线程以适当的顺序从两个文件中读取行
假设我有两个文件名A和B。如果 文件A包含: 嗨 你好吗 文件B包含: 我叫阿尤什 我做得很好 输出: 嗨 我叫阿尤什 你好吗 我做得很好 正如我所知,我们只能请求JVM,如果队列中的另一个线程没有准备好,那么下一个线程将再次执行。我尝试过使用标志和设置优先级,但我总是得到随机输出。有时第二个文件B中的行是先读取的,有时是从文件A中读取的。这扰乱了我想要答案的顺序在Java中使用多线程以适当的顺序从两个文件中读取行,java,multithreading,file-handling,Java,Multithreading,File Handling,假设我有两个文件名A和B。如果 文件A包含: 嗨 你好吗 文件B包含: 我叫阿尤什 我做得很好 输出: 嗨 我叫阿尤什 你好吗 我做得很好 正如我所知,我们只能请求JVM,如果队列中的另一个线程没有准备好,那么下一个线程将再次执行。我尝试过使用标志和设置优先级,但我总是得到随机输出。有时第二个文件B中的行是先读取的,有时是从文件A中读取的。这扰乱了我想要答案的顺序 import java.io.*; import java.util.*; class Synchronization{ p
import java.io.*;
import java.util.*;
class Synchronization{
public void readFromFile(Scanner sc) throws Exception{
while(sc.hasNext()){
System.out.println(sc.nextLine());
Thread.sleep(500);
}
}
}
class SynchronizedThreads extends Thread{
@Override
public void run(){
Scanner sc;
if(Thread.currentThread().getName().equals("A")){
try{
sc = new Scanner(new File("FirstFile.txt"));
object.readFromFile(sc);
}catch(Exception ex){
System.out.println(ex);
}
}else if(Thread.currentThread().getName().equals("B")){
try{
sc = new Scanner(new File("SecondFile.txt"));
object.readFromFile(sc);
}catch(Exception ex){
System.out.println(ex);
}
}
}
public static void main(String[] args) {
Synchronization object = new Synchronization();
SynchronizedThreads t1 = new SynchronizedThreads(object);
SynchronizedThreads t2 = new SynchronizedThreads(object);
//SynchronizedThreads t = new SynchronizedThreads(object);
t1.setName("A");
t2.setName("B");
//t.setName("Temp");
//t.start();
//t1.setPriority(10);
//t2.setPriority(5);
t1.start();
t2.start();
}
}
第二个代码
import java.util.*;
import java.io.*;
class ConcurrencyControl extends Thread{
volatile static boolean sema = true;
private String pathForFirstFile = "FirstFile.txt";
private String pathForSecondFile = "SecondFile.txt";
@Override//run() Method
public void run(){
String threadName = Thread.currentThread().getName();
if(threadName.equals("FirstFile")){
try{
Scanner sc = new Scanner(new File(pathForFirstFile));
if(sema == true){
while(sc.hasNextLine() /*&& sema == true*/){
System.out.println(sc.nextLine());
sema = false;
sleep(500);
}
}else{
sleep(500);
}
}catch(Exception ex){
System.out.println(ex);
}
}
else if(threadName.equals("SecondFile")){
try{
Scanner sc1 = new Scanner(new File(pathForSecondFile));
if(sema == false){
while(sc1.hasNextLine() /*&& sema == false*/){
System.out.println(sc1.nextLine());
sema = true;
sleep(500);
}
}else{
sleep(500);
}
}catch(Exception ex){
System.out.println(ex);
}
}
}
public static void main(String[] args){
ConcurrencyControl threadOne = new ConcurrencyControl();
threadOne.setName("FirstFile");
ConcurrencyControl threadSecond = new ConcurrencyControl();
threadSecond.setName("SecondFile");
threadOne.start();
threadSecond.start();
}
}
让一个标志显示
isATurn
。最初将i设置为true
。按顺序创建两个线程调用。将条件语句放入synchronized
块中,以检查回合数并相应地处理它。每次处理文件时都必须反转该标志
public void processA() {
while (!isATurn); //wait till processB method to invert the flag
synchronized(this) {
processNow();
isATurn = !isATurn;
}
}
以相同的方式实现processB
方法
编辑:Thread.sleep()
的级别稍低,使用它实现线程安全性比较困难。Java为我们提供了synchronized
关键字,以更优雅的方式处理这些问题
编辑:在synchronized
块外忙着等待,以避免CPU利用率低。同步应该怎么做?正如我看到的,你同时开始读取文件,并立即输出内容,而不需要等待任何东西(除了半秒的睡眠,但这是无条件的)。我不是这方面的专家,但它看起来像生产者/消费者,两个生产者给一个消费者。消费者将需要控制订单things@skandigraun该类只有一个我在SynchronizedThreads中调用的方法。实际上,我需要一个sleep方法,因为如果线程a从第一个文件中读取第一行,它应该等待线程B从第二个文件中读取第一行,并且应该保持顺序。我有点明白这个想法,但是这个方法总是随机和不可靠的,因为它依赖于运气。您可以引入一个锁或标志来指示何时可以读取文件。当A完成一行时,它将标志设置为“B_can_read”,然后进入睡眠状态,直到标志为“A_can_read”。B也是这样做的:如果标志是“B_can_read”,它会读取,并将标志设置为“A_can_read”,然后进入睡眠状态,等待轮到它。或者类似的东西,作为一个例子,我试着用这个逻辑。我正在编辑并发布第二个代码,请检查您是否可以在那里提供帮助。谢谢@skandigraun,而(!isATurn)
-这被称为。它有两个好处:1)非常低的延迟编程,2)创建风扇加热器。在这两个选项中,有一点需要注意,就是你已经将一个线程提升到100%,其他任何东西都无法使用它。这是一个非常糟糕的主意。我同意@Boristeider的观点,这个问题本身强加了一些秩序。如果任务是独立的,那么我们可以通过线程提高CPU利用率。我相信这种固有的命令强加总是会导致CPU利用率低下。欢迎您就如何提高效率提出建议。不正确。例如,使用wait()
,notify()
将允许等待线程返回到调度程序。如果您不知道如何编写并发代码,请不要发布答案。