Кусок из задачи 1:
public void run() {
           while (!isInterrupted()) {
               try {
                   if (reader.ready()) {
                       result.add(reader.readLine());
                       readStringCount.incrementAndGet();
                   }
               } catch (IOException e) {
                   e.printStackTrace();
               }
           }
           //add your code here - добавьте код тут
       }
Кусок из задачи 2:
public void run() {
            try {
                 if (reader.ready()) {
                     x = reader.readLine();
                     y = reader.readLine();
                     z = reader.readLine();
                 }
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
Прочитал почти все коменты, в общих чертах понял, почему в первой задачи необходим reader.ready(), немного понял из-за чего может работать неправильно во второй. Не могу понять одного, почему в первой задаче все работает, потоки ждут своей очереди, а во втором варианте даже не входит в блок инициализации, просто отрабатывает и выводит значения null
public static volatile AtomicInteger readStringCount = new AtomicInteger(0);
    public static volatile BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

    public static void main(String[] args) throws IOException {
        //read count of strings
        int count = Integer.parseInt(reader.readLine());

        //init threads
        ReaderThread consolReader1 = new ReaderThread();
        ReaderThread consolReader2 = new ReaderThread();
        ReaderThread consolReader3 = new ReaderThread();

        consolReader1.start();
        consolReader2.start();
        consolReader3.start();

        while (count > readStringCount.get()) {
        }

        consolReader1.interrupt();
        consolReader2.interrupt();
        consolReader3.interrupt();
        System.out.println("#1:" + consolReader1);
        System.out.println("#2:" + consolReader2);
        System.out.println("#3:" + consolReader3);

        reader.close();
    }

    public static class ReaderThread extends Thread {
        private List<String> result = new ArrayList<String>();

        public void run() {
            while (!isInterrupted()) {
                try {
                    if (reader.ready()) {
                        result.add(reader.readLine());
                        readStringCount.incrementAndGet();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            //add your code here - добавьте код тут
        }

        @Override
        public String toString() {
            return result.toString();
        }
    }
.....................................................................................
public static volatile BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

    public static void main(String[] args) throws InterruptedException {
        Read3Strings t1 = new Read3Strings();
        Read3Strings t2 = new Read3Strings();

        t1.start();
        t2.start();
        t1.join();
        t2.join();


        //add your code here - добавьте код тут

        t1.printResult();
        t2.printResult();
    }

    static class Read3Strings extends Thread {
        String x, y, z;

        @Override
        public void run() {
            try {
                 if (reader.ready()) {
                     x = reader.readLine();
                     y = reader.readLine();
                     z = reader.readLine();
                 }
            } catch (IOException e) {
                e.printStackTrace();
            }

        }

        void printResult() {

            System.out.println(x + " " + y + " " + z);

        }
    }