简体   繁体   English

Java计时器的多个线程

[英]Multiple Threads For a Java Timer

I am trying to write a short Java program that uses multiple threads to create a timer. 我正在尝试编写一个使用多个线程来创建计时器的简短Java程序。 When the timer hits 7 or 15 seconds, it will print a message. 当计时器达到7或15秒时,它将打印一条消息。

I need to create a shared counter. 我需要创建一个共享计数器。 A time-printing thread increments the counter by one and prints its value each second from the start of execution. 时间打印线程将计数器递增1并从执行开始每秒打印其值。 A message-printing thread prints a message every fifteen seconds and another message-printing thread that prints a different message every seven seconds. 消息打印线程每十五秒打印一条消息,另一个消息打印线程每七秒打印一条不同的消息。 These two threads need to be done without modifying the time-printing thread. 需要在不修改时间打印线程的情况下完成这两个线程。

All these threads need to share the counter object that updates every second. 所有这些线程都需要共享每秒更新的计数器对象。 The time-printing thread will notify other threads to read the counter object each time it updates. 时间打印线程将通知其他线程每次更新时读取计数器对象。 Then, each message-printing thread will read the counter value and see if its assigned time period has occured. 然后,每个消息打印线程将读取计数器值并查看其分配的时间段是否已发生。

The output should look like this: 输出应如下所示:

1 2 3 4 5 6
7 second message
7 8 9 10 11 12 13
7 second message
14
15 second message
15 16 17 18 19 20
7 second message
21 22 23 24  . . .

I need to do this by creating a thread for the timer, a thread for the 7 second message, and a thread for the 15 second message. 我需要通过为计时器创建一个线程,为7秒消息创建一个线程,为15秒消息创建一个线程来实现这一点。 I've built this below: 我在下面构建了这个:

import java.lang.Class;
import java.lang.Object;

class T1 extends Thread {
    private Main2 s;
    private int t;
    T1 (Main2 s) { this.s = s; }
    public void run()
    {
        while(true) {
            try { Thread.sleep(1000); }
            catch (InterruptedException e) { e.printStackTrace(); }
            s.setSharedTime (++t);
            System.out.print(t + " ");
        }
    }
}

class T2 extends Thread {
    private Main2 s;
    T2 (Main2 s) { this.s = s; }
    public void run()
    {
        while(true) { 
            int t = s.getSharedTime ();
            System.out.println();
            System.out.println ("7 second message");
        }
    }
}

class T3 extends Thread {
    private Main2 s;
    T3 (Main2 s) { this.s = s; }
    public void run()
    {
        while(true) { 
            int t = s.getSharedTime ();
            System.out.println();
            System.out.println ("15 second message");
        }
    }
}

public class Main2 {
    private int time;
    private boolean share = true;

    public static void main(String[] args) {
        Main2 s = new Main2();
        new T1 (s).start();
        new T2 (s).start();
        new T3 (s).start();
    }

    synchronized void setSharedTime (int s) {
        while (!share) {
            try { wait (); }
            catch (InterruptedException e) {}
        }
        this.time = s;
        if(s % 7 == 0)
            share = false;
        if(s % 15 == 0)
            share = false;
        notify ();
    }

    synchronized int getSharedTime () {
        while (share) {
            try { wait (); }
            catch (InterruptedException e) { }
        }
        share = true;
        notify ();
        return time;
    }
}

The problem I'm having with this is I cannot throw the 7 second and 15 second messages at the right times. 我遇到的问题是我不能在正确的时间抛出7秒和15秒的消息。 How do I run these three threads together to put together a working timer? 如何将这三个线程组合在一起组成一个工作计时器?

In your code, you use classes T2 and T3 to print the 7 and 15 second messages, but there is no identification of which is which and they are effectively identical, save the name and the String that is printed. 在您的代码中,您使用类T2和T3来打印7秒和15秒的消息,但是没有标识哪个是哪个并且它们实际上是相同的,保存名称和打印的字符串。 When notify() is called there is no specifiable order in which the lock is given. 当调用notify()时,没有给出锁定的可指定顺序。 From the Javadocs for notify(): 来自Javadocs的notify():

The awakened threads will compete in the usual manner with any other threads that might be actively competing to synchronize on this object 唤醒的线程将以通常的方式与可能主动竞争同步此对象的任何其他线程竞争

So whichever method (run() of T2 or run() of T3) that gets the lock on getSharedTime() will continue and print. 因此,无论哪种方法(T3的run()或T3的run()获得锁定getSharedTime()都将继续并打印。 Look at this question and the Javadocs for more information on that. 请查看此问题Javadocs以获取更多相关信息。

This is a similar way to do the same thing, I moved the checking if the time is a multiple of 7 or 15 to their respective classes, and structured the wait()'s and notify()'s differently. 这是做同样事情的类似方法,如果时间是各自类的7或15的倍数,我移动了检查,并且以不同方式构造了wait()和notify()。 I also synchronized the printing with the Timer class so that all of the wait()'s are notified (effectively) at the same time. 我还将打印与Timer类同步,以便同时(有效地)通知所有wait()。 Printing the time at each second is handled in the Timer class, and the way that it is setup now will give the output that you specified, but switching the printing and call of setTime and initializing time to 0 will give an output that is more accurate to the current time. 打印每秒的时间在Timer类中处理,现在设置它的方式将给出你指定的输出,但切换打印和调用setTime并初始化时间为0将提供更准确的输出到了现在。

class Timer extends Thread{
    private int time = 1;
    private boolean setting = false;

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

            System.out.print(time + " ");
            setTime(time + 1);
            //Switching the order of these 2 ^^^ statements and initializing time to 0 will give an output that is more accurate to the time.
        }
    }
    public synchronized int getTime(){
        while(setting){
            try {
                wait(); //This will only be run on the off-chance that setTime is being run at the same time.
            } catch (InterruptedException e) {  }
        }

        return time;
    }
    public synchronized void setTime(int t){
        setting = true;
        this.time = t;
        setting = false;
        notifyAll();
    }
}

class Timer7 extends Thread{
    Timer timer;
    public Timer7(Timer t){
        this.timer = t;
    }

    public void run(){
        synchronized(timer){
            while(true){

                try {
                    timer.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                if(timer.getTime() % 7 == 0){
                    System.out.print("\n7 Second Message\n");
                }

            }
        }
    }
}

class Timer15 extends Thread{
    Timer timer;
    public Timer15(Timer t){
        this.timer = t;
    }

    public void run(){
        synchronized(timer){
            while(true){

                try {
                    timer.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                if(timer.getTime() % 15 == 0){
                    System.out.print("\n15 Second Message\n");
                }

            }
        }
    }
}

public class Main2 {

    public static synchronized void main(String[] args) {

        Timer timer = new Timer();
        timer.start();

        Timer7 t7 = new Timer7(timer);
        t7.start();

        Timer15 t15 = new Timer15(timer);
        t15.start();

    }

}

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

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