使用Java中的多线程以适当的顺序从两个文件中读取行

时间:2018-09-22 15:08:20

标签: java multithreading file-handling

假设我有两个文件,分别为A和B。如果,

文件A包含:

嗨。

你好吗?

文件B包含:

我叫Ayush。

我做得很好。

输出:

HI。

我叫Ayush。

你好吗?

我做得很好。

据我所知,我们只能请求JVM,并且如果队列中的其他线程尚未就绪,则再次执行下一个线程。我尝试使用标志并设置优先级,但是我总是得到随机输出。有时,第二个文件B中的行首先被读取,有时从文件A中读取。这打乱了我想要答案的顺序。

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();
    }
}

1 个答案:

答案 0 :(得分:-1)

带有一个标语isATurn。最初将isATurn设置为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使用率降低。