当前位置: 首页 > 知识库问答 >
问题:

Java定时器的多线程

宗政卓
2023-03-14

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

我需要创建一个共享计数器。时间打印线程将计数器递增1,并从执行开始每秒打印其值。一个消息打印线程每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秒的消息。我如何将这三个线程一起运行,以组成一个工作计时器?

共有1个答案

岳阳文
2023-03-14

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

被唤醒的线程将以通常的方式与任何其他线程竞争,这些线程可能会积极地在这个对象上进行同步

因此,无论哪个方法(T2的run()或T3的run())获得getSharedTime()上的锁,都将继续并打印。查看这个问题和Javadocs以获取更多信息。

这是一种类似的方法来做同样的事情,我将检查时间是否是7或15的倍数移动到他们各自的类中,并以不同的方式构造了等待()和通知()。我还将打印与Timer类同步,以便同时(有效地)通知所有等待()。在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();

    }

}
 类似资料:
  • 本文向大家介绍java实现多线程之定时器任务,包括了java实现多线程之定时器任务的使用技巧和注意事项,需要的朋友参考一下 在Java中Timer是java.util包中的一个工具类,提供了定时器的功能。我们可以创建一个Timer对象,然后调用其schedule方法在某个特定的时间去执行一个特定的任务。并且你可以让其以特定频率一直执行某个任务,这个任务是用TimerTask来描述的,我们只需要将要

  • 我使用Timer和TimerTask为聊天应用程序长轮询新消息。我想研究两种“稍微”不同的可能性: 1:计时器声明为局部变量 *问题:每次调用该方法时,我都会看到创建了一个新线程,[Timer-1]、[Timer-2]等等。。在Eclipse调试窗口中,即使在getLastMessages(..)之后,它们似乎都在运行完成运行并向客户端返回值。如果计时器实际使用线程,并且在几次事务之后,服务器最终

  • 我想做的工作是在初始设置中模拟一个停止和等待java.TheARQ < li >创建一个< code >服务器套接字。 < li >对于每个接受的客户端,使用ServerSocket.accept为该客户端创建一个新线程。 现在,我基本上想做的主要部分。 > 向客户端发送一个数据包。(或一些数据给客户端) 等待1秒,但如果确认在该时间内到达,则中断等待时间并进入下一个循环 这里的问题是,这个作为阻

  • 本文向大家介绍Java 定时器(Timer)及线程池里使用定时器实例代码,包括了Java 定时器(Timer)及线程池里使用定时器实例代码的使用技巧和注意事项,需要的朋友参考一下 java Timer定时器 简单实例代码: 线程池里的定时器 感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

  • 我有两个线程,一个在一个套接字上监听并添加到队列中,另一个从队列中减去并提交处理。第二个线程在队列为空时Hibernate。这个睡眠不知怎么会影响第一个线程,也就是说,如果您移除睡眠或使它变大,那么第一个线程的socket.receive中的延迟就会增加。如果我保持尽可能低的睡眠,它会变得更好,但不是完美的。我做错了什么?

  • 本文向大家介绍C#多线程学习之(五)使用定时器进行多线程的自动管理,包括了C#多线程学习之(五)使用定时器进行多线程的自动管理的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了C#多线程学习之使用定时器进行多线程的自动管理。分享给大家供大家参考。具体分析如下: Timer类:设置一个定时器,定时执行用户指定的函数。 定时器启动后,系统将自动建立一个新的线程,执行用户指定的函数。 初始化一个T