Как я могу напечатать, как показано ниже, используя метод синхронизации потоков?

#java #multithreading #oop #synchronization #synchronized

#java #многопоточность #ооп #синхронизация #синхронизировано

Вопрос:

Я использовал метод синхронизации потоков для печати кода ASCII и его значения, как показано в примере ниже.
Например: —
A
65
B
66
C
67
.
.
.
.
Z
90

Но результат таков.

введите описание изображения здесь

Ниже приведены два потока.

Поток 1

 public class PrintingASCII extends Thread{
    private Object ob;
    
    public PrintingASCII(Object ob) {
        this.ob = ob;
    }
    
    public void run() {
        synchronized(ob) {
            for(int i=65;i<=90;i  ) {
                System.out.println(i);
            }
        }
    }
}
 

Поток 2

 public class PrintingCapital extends Thread{
    private Object ob;
    
    public PrintingCapital(Object ob) {
        this.ob = ob;
    }
    
    public void run() {
        synchronized(ob) {
            for(char i='A';i<='Z';i  ) {
                System.out.println(i);
            }
        }
    }   
}
 

Главная

 public class Main {

    public static void main(String[] args) {
        Object ob = new Object();
        System.out.println("PLAAA");
        PrintingASCII thread1 = new PrintingASCII(ob);
        PrintingCapital thread2 = new PrintingCapital(ob);
        thread1.start();
        thread2.start();
    }
}
 

Что я могу для этого сделать, не меняя метод main?

Комментарии:

1. Добавить ob.wait() перед одним из System.out.println и ob.notify() перед другим

2. и поместите syncronized внутри циклов вокруг этих вызовов ожидания / уведомления, что-то вроде for(char i='A';i<='Z';i ) {synchronized(ob) {ob.wait();} System.out.println(i);}

Ответ №1:

Это можно решить с помощью двух объектных мониторов.

  1. Один монитор объекта должен уведомлять PrintingCapital после печати ASCII-кода.
  2. Второй монитор объекта должен уведомлять PrintingASCII после печати определенного значения ASCII.

Таким образом, два потока печатают свои значения поочередно для достижения требуемого результата.

Я использовал String.class в качестве второго монитора объекта, так как основной не может быть изменен. Вы можете использовать любой другой объект в качестве монитора, если у вас есть доступ к основному методу.

 class PrintingASCII extends Thread {
    private Object ob1;
    private Object ob2;

    public PrintingASCII(Object ob1) {
        this.ob1 = ob1;
    }

    public void run() {
            try {
                for (int i = 65; i <= 90; i  ) {
                    synchronized(ob1) {ob1.wait();} 
                    System.out.println(i);
                    synchronized(String.class) {String.class.notify();}
                }
            }catch (Exception e) {
                System.out.println("Exc : " e);
            }
    }
}

class PrintingCapital extends Thread {
    private Object ob1;
    private Object ob2;

    public PrintingCapital(Object ob1) {
        this.ob1 = ob1;
    }

    public void run() {
        try {
            for (char i = 'A'; i <= 'Z'; i  ) {
                System.out.println(i);
                synchronized(ob1) {ob1.notify();}
                synchronized(String.class) {String.class.wait();}
            }
        }catch (Exception e) {
            System.out.println("Exc : " e);
        }
    }
}

public class Main {

    public static void main(String[] args) {
        Object ob1 = new Object();
        PrintingASCII thread1 = new PrintingASCII(ob1);
        PrintingCapital thread2 = new PrintingCapital(ob1);
        thread1.start();
        thread2.start();
        
    }
}