简体   繁体   English

线程之间的通信问题

[英]Issues in communication between threads

I am trying to work out a problem described below. 我正在尝试解决以下问题。

Write a program that prints message from the start of execution, with another thread that prints a message for every fifteenth message. 编写一个从执行开始就打印消息的程序,并使用另一个线程为每第十五条消息打印一条消息。 Have the message-printing thread be notified by the message-printing thread as each message is printed by. 在打印每条消息时,使消息打印线程通知消息打印线程。 Add another thread that prints a different message every seventh message without modifying the message-printing thread. 添加另一个线程,该线程每隔七个消息打印一次不同的消息,而无需修改消息打印线程。

I have tried the following. 我尝试了以下方法。 can any one guide me as how do I call a particular thread in the program. 任何人都可以指导我如何在程序中调用特定线程。

This class is used for 该类用于

public class Message{
    String message; 
    volatile boolean flag=true;

    synchronized void printMessage(String message){
        int count=16;


        for(int i=0;true;){
            i++;

            if(i%15==0 || i%7==0){
                try {
                    wait();
                } catch (InterruptedException e) {

                    e.printStackTrace();
                }               
            }

            System.out.println(i +" "+message);
        notify();           
            }           

    }

synchronized void printMessageFifteen(String message){          

    System.out.println(message);
    notify();   

    try {
        wait();
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }                       

}

synchronized void printMessageSeven(String message){            

    System.out.println(message);
    notify();   

    try {
        wait();
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
            e.printStackTrace();
        }                       

    }



}

Threads that prints out the message in a continuous manner: 以连续方式打印出消息的线程:

public class ContinousMessageThread extends Thread{

    Message messageObject;

    ContinousMessageThread(Message messageObject){
        this.messageObject=messageObject;
        new Thread(this,"seconds").start();
    }

    @Override
    public void run() {

        messageObject.printMessage(this.messageObject.message);
    }

}

Thread that prints out the message for every fifteen seconds: 每十五秒钟打印出一条消息的线程:

public class FifteenSecondsMessageThread extends Thread{

    Message messageObject;

    public FifteenSecondsMessageThread(Message messageObject) {
        this.messageObject=messageObject;       
        new Thread(this,"seconds").start();

    }

    @Override
    public void run() {
        while(true){
        messageObject.printMessageFifteen("Fifteen Seconds over");
        }
    }

}

Thread that prints out message for every seven seconds 每七秒钟打印一次消息的线程

public class SevenSecondsMessageThread extends Thread {
    Message messageObject;


    public SevenSecondsMessageThread(Message messageObject) {
        this.messageObject=messageObject;       
        new Thread(this,"seconds").start();

    }

    @Override
    public void run() {
        while(true){
            messageObject.printMessageSeven("Seven Seconds over");
        }   
    }

}

Main class where all the threads are started.. 启动所有线程的主类。

public class MainClass {
public static void main(String[] args) {
    Object sevenSecond= new Object();
    Object fifteenSecond= new Object();


    Message messageObject= new Message();
    messageObject.message="seconds";



    ContinousMessageThread continousMessageThreadObject= new ContinousMessageThread(messageObject);
    SevenSecondsMessageThread secondsMessageThreadObject = new SevenSecondsMessageThread(messageObject);
    FifteenSecondsMessageThread fifteenSecondsMessageThreadObject=new FifteenSecondsMessageThread(messageObject); 

}

Output That I am getting : 我得到的输出:

    1 seconds
    2 seconds
    3 seconds
    4 seconds
    5 seconds
    6 seconds
    Seven Seconds over
    7 seconds
    8 seconds
    9 seconds
    10 seconds
    11 seconds
    12 seconds
    13 seconds
    Seven Seconds over
    14 seconds
    Seven Seconds over
    15 seconds
    16 seconds
    17 seconds
    18 seconds
    19 seconds
    20 seconds
    Seven Seconds over
    21 seconds
    22 seconds
    23 seconds
    24 seconds
    25 seconds
    26 seconds
    27 seconds
    Seven Seconds over
    Fifteen Seconds over
    Seven Seconds over
    28 seconds
    29 seconds
    Seven Seconds over
    Fifteen Seconds over
    30 seconds
    31 seconds
    32 seconds
    33 seconds
    34 seconds
    Fifteen Seconds over
    Seven Seconds over

Expected result is 预期结果是

    1 seconds
    2 seconds
    3 seconds
    4 seconds
    5 seconds
    6 seconds
    Seven Seconds over
    7 seconds
    8 seconds
    9 seconds
    10 seconds
    11 seconds
    12 seconds
    13 seconds
    Seven Seconds over
    14 seconds
    Fifteen Seconds over
    15 seconds
    16 seconds
    17 seconds
    18 seconds
    19 seconds
    20 seconds
    Seven Seconds over
    21 seconds
    22 seconds
    23 seconds
    24 seconds
    25 seconds
    26 seconds
    27 seconds
    Seven Seconds over
    28 seconds
    29 seconds
    Fifteen Seconds over
    30 seconds
    31 seconds
    32 seconds
    33 seconds
    34 seconds
    Seven Seconds over

Note: 注意:

The program works perfectly fine (on expected lines) when only SevenSecondMessageThread and ContiniousMessageThread or FifteenSecondMessageThread and ContiniousMessageThread are called. 仅调用SevenSecondMessageThread和ContiniousMessageThread或FifteenSecondMessageThread和ContiniousMessageThread时,程序运行良好(在预期的行上)。 But it fails when All the threads are called. 但是在调用所有线程时失败。 I am not able to understand why this is happening and how can I avoid this? 我不明白为什么会这样,如何避免这种情况?

To obtain the desired behaviour, you could think in terms of objects to be synchronized. 为了获得所需的行为,您可以考虑要同步的对象。 In this case, I defined two Object (sevenSecond and fifteenSecond) and I make synchronize the continuous thread on these two objects, so that we can define exactly which thread start or stop. 在这种情况下,我定义了两个对象(sevenSecond和十五秒),并使这两个对象上的连续线程同步,以便我们可以准确地定义哪个线程开始或停止。

Here's a modified version of your code that implements the main idea of having a continuous thread that from time to time is interrupted by the other two: 这是代码的修改后的版本,实现了具有不时被其他两个中断的连续线程的主要思想:

    public static void main(String[] args){

        Object sevenSecond= new Object();
        Object fifteenSecond= new Object();

        Message messageObject= new Message();
        messageObject.message="seconds";

        ContinousMessageThread continousMessageThreadObject= new ContinousMessageThread(messageObject);
        SevenSecondsMessageThread secondsMessageThreadObject = new SevenSecondsMessageThread(messageObject);
        FifteenSecondsMessageThread fifteenSecondsMessageThreadObject=new FifteenSecondsMessageThread(messageObject);
    }


    static class Message{
        String message;
        Object sevenLock = new Object();
        Object fifteenLock = new Object();

        void printMessage(String message) {

            try {
                for(int i=0; true; i++){
                    if (i % 7 == 0) {
                        synchronized (sevenLock) {
                            sevenLock.notify();
                            System.out.println(i + " " + message);
                            sevenLock.wait();
                        }
                    }
                    else if (i % 15 == 0) {
                        synchronized (fifteenLock) {
                            fifteenLock.notify();
                            System.out.println(i + " " + message);
                            fifteenLock.wait();
                        }
                    }
                    else {
                        System.out.println(i + " " + message);
                        System.out.flush();
                    }
                    if (i == 50) System.exit(-1);  // stops after a few iterations
                }
            }
            catch(InterruptedException e) {
                e.printStackTrace();
            }

        }

        void printMessageFifteen(String message) {
            try {
                synchronized (fifteenLock) {
                    System.out.println(message);
                    fifteenLock.notify();
                    fifteenLock.wait();
                }
            }
            catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        synchronized void printMessageSeven(String message) {
            try {
                synchronized (sevenLock) {
                    System.out.println(message);
                    sevenLock.notify();
                    sevenLock.wait();
                }
            }
            catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    static class ContinousMessageThread extends Thread {

        Message messageObject;

        ContinousMessageThread(Message messageObject){
            this.messageObject=messageObject;
            new Thread(this,"seconds").start();
        }

        @Override
        public void run() {
            messageObject.printMessage(this.messageObject.message);
        }

    }


    static class FifteenSecondsMessageThread extends Thread{

        Message messageObject;

        public FifteenSecondsMessageThread(Message messageObject) {
            this.messageObject=messageObject;
            new Thread(this,"seconds").start();

        }

        @Override
        public void run() {
            while(true){
                messageObject.printMessageFifteen("Fifteen Seconds over");
            }
        }

    }

    static class SevenSecondsMessageThread extends Thread {
        Message messageObject;


        public SevenSecondsMessageThread(Message messageObject) {
            this.messageObject=messageObject;
            new Thread(this,"seconds").start();

        }

        @Override
        public void run() {
            while(true){
                messageObject.printMessageSeven("Seven Seconds over");
            }
        }

    }

Note that, as in your version, the first time the two threads (7 and 15) output their message is not related to the continuous thread (they can appear everywhere between 0 and 7 or 15); 请注意,与您的版本一样,两个线程(7和15)第一次输出其消息与连续线程无关(它们可以出现在0到7或15之间的任何位置)。 from the second on, they have the desired behaviour. 从第二开始,他们就拥有了期望的行为。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM