线程之间的通信问题

时间:2015-07-24 06:55:03

标签: java multithreading thread-safety

我正在尝试解决下面描述的问题。

编写一个程序,从执行开始打印消息,另一个线程为每第15个消息打印一条消息。在打印每条消息时,消息打印线程会通知消息打印线程。添加另一个线程,每隔七个消息打印一条不同的消息,而不修改消息打印线程。

我尝试了以下内容。任何人都可以指导我如何调用程序中的特定线程。

此类用于

$(document).ready(function()
{   
    if($("#example_filter input").length > 0)
    {
        alert("search exists");
    }
    $(document).on("keyup",'#example_filter input',function(){
       alert("hi");    
    }); //event delegation
    $("#example").DataTable();
});

以连续方式打印出消息的线程:

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

}

每7秒打印一次消息的线程

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

注意:

当只调用SevenSecondMessageThread和ContiniousMessageThread或FifteenSecondMessageThread和ContiniousMessageThread时,程序完全正常(在预期的行上)。但是当调用所有线程时它会失败。我无法理解为什么会这样,我怎么能避免这种情况?

1 个答案:

答案 0 :(得分:2)

要获得所需的行为,您可以根据要同步的对象进行思考。在这种情况下,我定义了两个Object(sevenSecond和15Second)并且我在这两个对象上同步连续线程,这样我们就可以确切地定义哪个线程开始或停止。

这是你的代码的修改版本,它实现了一个连续线程的主要思想,这个线程不时被其他两个中断:

    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之间的任何位置);从第二个开始,他们就有了理想的行为。