簡體   English   中英

線程之間的通信問題

[英]Issues in communication between threads

我正在嘗試解決以下問題。

編寫一個從執行開始就打印消息的程序,並使用另一個線程為每第十五條消息打印一條消息。 在打印每條消息時,使消息打印線程通知消息打印線程。 添加另一個線程,該線程每隔七個消息打印一次不同的消息,而無需修改消息打印線程。

我嘗試了以下方法。 任何人都可以指導我如何在程序中調用特定線程。

該類用於

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

    }



}

以連續方式打印出消息的線程:

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

}

每十五秒鍾打印出一條消息的線程:

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

}

每七秒鍾打印一次消息的線程

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

}

啟動所有線程的主類。

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

}

我得到的輸出:

    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

預期結果是

    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

注意:

僅調用SevenSecondMessageThread和ContiniousMessageThread或FifteenSecondMessageThread和ContiniousMessageThread時,程序運行良好(在預期的行上)。 但是在調用所有線程時失敗。 我不明白為什么會這樣,如何避免這種情況?

為了獲得所需的行為,您可以考慮要同步的對象。 在這種情況下,我定義了兩個對象(sevenSecond和十五秒),並使這兩個對象上的連續線程同步,以便我們可以准確地定義哪個線程開始或停止。

這是代碼的修改后的版本,實現了具有不時被其他兩個中斷的連續線程的主要思想:

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

    }

請注意,與您的版本一樣,兩個線程(7和15)第一次輸出其消息與連續線程無關(它們可以出現在0到7或15之間的任何位置)。 從第二開始,他們就擁有了期望的行為。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM