【问题标题】:Multiple Threads For a Java TimerJava 计时器的多线程
【发布时间】:2016-05-02 23:32:36
【问题描述】:

我正在尝试编写一个使用多个线程来创建计时器的简短 Java 程序。当计时器达到 7 或 15 秒时,它将打印一条消息。

我需要创建一个共享计数器。时间打印线程将计数器加一并从执行开始每秒打印其值。一个消息打印线程每 15 秒打印一个消息,另一个消息打印线程每 7 秒打印一个不同的消息。这两个线程需要在不修改时间打印线程的情况下完成。

所有这些线程都需要共享每秒更新的计数器对象。每次更新时,时间打印线程都会通知其他线程读取计数器对象。然后,每个消息打印线程将读取计数器值并查看其分配的时间段是否已经发生。

输出应如下所示:

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  . . .

我需要为计时器创建一个线程,为 7 秒消息创建一个线程,为 15 秒消息创建一个线程。我在下面构建了这个:

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

我遇到的问题是我无法在正确的时间抛出 7 秒和 15 秒的消息。如何同时运行这三个线程来组合一个工作计时器?

【问题讨论】:

  • 您想如何将它们组合在一起?我认为线程一起工作的目的尚不清楚。您是否只想要两个完全独立且完全不相互依赖的线程?
  • 是的,我会编辑问题以尝试清楚。

标签: java multithreading timer


【解决方案1】:

在您的代码中,您使用类 T2 和 T3 来打印 7 秒和 15 秒的消息,但是没有标识哪个是哪个,它们实际上是相同的,保存名称和打印的字符串。当调用 notify() 时,没有指定的锁定顺序。来自 notify() 的 Javadocs:

被唤醒的线程将以通常的方式与任何其他可能正在积极竞争以在此对象上同步的线程竞争

因此,获得 getSharedTime() 锁定的任何方法(T2 的 run() 或 T3 的 run())都将继续并打印。查看this questionJavadocs 了解更多信息。

这是做同样事情的类似方法,我将检查时间是否是 7 或 15 的倍数移至它们各自的类,并以不同的方式构造 wait() 和 notify()。我还将打印与 Timer 类同步,以便同时(有效地)通知所有 wait()。每秒打印时间在 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();

    }

}

【讨论】:

  • 太棒了。谢谢你的帮助,我想我现在明白了。
猜你喜欢
  • 2015-07-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-02
  • 2016-09-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多