How to do 3 thread communication in JAVA?

Rasheeq Ishmam :

I am making a 3 thread communication. User will input the message for the thread to communicate. The threads suppose to communicate until one of the thread says "Bye". But in my program thread 1 execute only once then gone and the other two threads continue communicate.

The Output of my program looks like this.

Here is the code:

        import java.util.Scanner;

    public class Conversation {
        public static void main(String[] args) {

            Chat chat = new Chat();

           new Thread1(chat).start();
           new Thread2(chat).start();
           new Thread3(chat).start();
        }
    }



    class Chat {
        Scanner sc1 = new Scanner(System.in);
        Scanner sc2 = new Scanner(System.in);
        Scanner sc3 = new Scanner(System.in);
        String str1,str2,str3;
        int flag = 0;

        public synchronized void getTalk1() throws InterruptedException {
        if (flag==1 ) {
            wait();
        }
        System.out.print("User1: ");
        str1 = sc1.nextLine();
        if(str1.equalsIgnoreCase("bye")) {
            System.out.println("\nUser1 has left the chat. Conversation ended.");
            System.exit(0);
        }
        flag = 1;
        notifyAll();
    }

        public synchronized void getTalk2() throws InterruptedException {
        if (flag == 0) {
            wait();
        }
        System.out.print("User2: ");
        str2 = sc2.nextLine();
        if(str2.equalsIgnoreCase("bye")) {
            System.out.println("\nUser2 has left the chat. Conversation ended.");
            System.exit(0);
        }

        flag = 0;
        notifyAll();
        }

        public synchronized void getTalk3() throws InterruptedException {
            if (flag == 3) {
                wait();
            }
            System.out.print("User3: ");
            str3 = sc3.nextLine();
            if(str3.equalsIgnoreCase("bye")) {
                System.out.println("\nUser3 has left the chat. Conversation ended.");
                System.exit(0);
            }


            flag = 3;
            notifyAll();
            }



    }






    class Thread1 extends Thread {
    Chat chat;

    public Thread1(Chat chat) {
        this.chat = chat;
    }


    public void run() {
        try {
            while(true) {
                chat.getTalk1();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        }
    }

    class Thread2 extends Thread {
    Chat chat;

    public Thread2(Chat chat) {
        this.chat = chat;
    }


    public void run() {
        try {
            while(true) {
                chat.getTalk2();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        }
    }

    class Thread3 extends Thread {
        Chat chat;

        public Thread3(Chat chat) {
            this.chat = chat;
        }


        public void run() {
            try {
                while(true) {
                    chat.getTalk3();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            }
        }
Andrew Tobilko :

You don't necessarily need to create 3 separate Thread classes for 3 users. You also don't need 3 separate methods for each user. It's hard to read, maintain, and debug.

I wrote a very simple program for you. In your application, synchronised is used to wrap the whole method. It's hard to read, and it's unclear why you synchronised the entire method body. In my example, there is a single point where synchronisation is required and it's well defined: when a user wants to say something to the chat.

Have a look.

class Application {

    public static void main(String[] args) {
        final Chat chat = new Chat();

        chat.registerUser(new User("user1", chat));
        chat.registerUser(new User("user2", chat));
        chat.registerUser(new User("user3", chat));
    }

}

class Chat {

    private final Scanner scanner = new Scanner(System.in);
    private final List<User> users = new ArrayList<>();

    private void registerUser(User user) {
        users.add(user);
        System.out.format("'%s' connected to the chat.\n", user);
        user.start();
    }

    public void sendMessage(User user) {
        final String reply = scanner.nextLine();
        System.out.format("%s: %s\n", user, reply);

        if (reply.equalsIgnoreCase("bye")) {
            users.forEach(Thread::interrupt);
            System.out.println("The chat is over.");
        } else {
            notifyAll();
        }
    }

}

class User extends Thread {

    private final String id;
    private final Chat chat;

    public User(String id, Chat chat) {
        this.id = id;
        this.chat = chat;
    }

    public void run() {
        while (true) {
            try {
                synchronized (chat) {
                    chat.sendMessage(this);
                    chat.wait();
                }
            } catch (InterruptedException e) {
                throw new IllegalArgumentException("Someone left. I am done as well.");
            }
        }
    }

    @Override
    public String toString() {
        return id;
    }

}

An example would be

'user1' connected to the chat.
'user2' connected to the chat.
'user3' connected to the chat.
hi
user1: hi
hello
user3: hello
what's up?
user2: what's up?
nothing
user3: nothing
what?
user1: what?
bye
user2: bye
The chat is over.

To read:

the producer–consumer problem

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=141388&siteId=1