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

如何让线程在特定时间等待通知,并根据是否收到通知执行代码?

云和硕
2023-03-14

我正在尝试实现一些UDP的变体。

服务器线程接收数据报数据包,对其进行解析,并将其传递给相应的线程。如果它收到一条消息,它会回复一条确认消息,并将其传递给ReceiveMessage线程,该线程会在屏幕上打印该消息。

我有一个SendMessage线程和一个ReceiveMessage线程。

我希望SendMessage线程发送一个数据包,并在特定的超时时间内等待确认。如果服务器收到确认,我想向SendMessage发送notify(),如果没有,我想让SendMessage线程超时,并在这两种情况下执行不同的代码。我怎样才能做到这一点?

public class ListenThread extends Thread{

protected DatagramSocket socket = null;
protected Boolean on = true;
protected String id;
protected HashMap <String,Contact> people = null;
protected String user;


public ListenThread(String macadd, String user, HashMap <String, Contact> people) throws SocketException
{
    super("ListenThread");
    this.socket = new DatagramSocket(3333);
    this.id=macadd;
    this.people = people;
    this.user = user;
}

@Override
public void run()
{


    while (on) 
            {

                byte[] buf = new byte[256];
                try{
                        // receive request
                        DatagramPacket packet = new DatagramPacket(buf, buf.length);
                        socket.receive(packet);

                        String packdetails[] = new String(packet.getData(), 0, packet.getLength()).split(":");//Important part of receiving request. Tool used to parse the request
                        InetAddress address = packet.getAddress();

                        if(packdetails[0].equals("D"))  // if it's a Detection Packet                   
                        {/* Handle what to do with Detection packets */
                            }// end of small if
                        }//end of big if
                        else if(packdetails[0].equals("M"))// implies, Message type packet
                        {
                            Timestamp t =new Timestamp(new Date().getTime());
                            //Send Acknowledgement
                            String PString = new String("A:"+id);
                            buf = PString.getBytes();
                            packet = new DatagramPacket(buf, buf.length, address, 3333);

                            new ReceiveMessage(packdetails, address, people, t).start();
                        }
                        else// if it's an acknowledgemnt
                        {
                            //notify the sendmessage thread
                        }
                    }//end of try
                    catch (UnknownHostException e) 
                    {
                        System.err.print("Unable to find IP of current machine");
                    }
                    catch (IOException except)
                    {
                        System.err.print("Network Problem : Unable to send packets!");
                    }
            }//end of while
    }//end of run

}//课程结束

public class SendMessage extends Thread{
protected Contact person = null;
protected String Message = null;

public SendMessage(Contact person, String Message)
{
    this.person=person;
    this.Message= Message;
}
@Override
public void run()
{
    System.out.println(person.getusername()+": "+Message);
    try
    {
        person.SendMessage(Message);
        Thread.currentThread().wait(500);// If i get notify => received acknowledgement
    }
    catch(IOException e)
    {
        System.err.println("Unable to send message!");
    }
    catch (InterruptedException e)
    {
        System.err.print("Woken before receiving notify");
    }
}

共有2个答案

田意致
2023-03-14

有很多方法可以实现这一点,您可以选择CountDownLatch或CyclicBarrier,其中发送方线程将等待接收方对屏障进行操作。另一种选择是,接收方线程将ack消息放入blockingQueue,发送方可以在等待队列时使用队列中的ack。

扶誉
2023-03-14

使用条件。等待(超时,…) 而不是对象。等待()

 类似资料:
  • 问题内容: 我写了一个永远不会停止的测试应用程序。它发出(是一个对象),但是我从不打电话通知。为什么此代码结束?尽管主线程在上同步,但生成的线程仍在运行,因此不会锁定该对象。 结果是主线程等待5秒钟,在此期间工作人员提供其输出。然后,在5秒钟后,程序退出。不等。如果主线程在5秒钟内没有进入睡眠状态(对此行进行了注释),则实际上将等到工作人员完成操作。当然,这里是一种使用方法,但是,出乎意料的是,它

  • 我不完全理解和()是如何工作的,因此我不得不将尝试缩减到以下代码部分。 main.java: runner.java: 当前,我在调用时得到一个非法MonitorStateException,但我不明白为什么。从我所看到的情况来看,我需要同步,但在这样做的时候,我假设它只会通知一个线程,而我的想法是通知所有线程。 我已经查看了,但是我找不到合适的替换(也许我只是遗漏了一些东西)。

  • 我是多线程的新手,当我阅读有关多线程的内容时,我想编写这个精美的多线程代码来执行以下操作。 我的柜台类如下。 这个计数器对象由两个线程共享。一旦线程启动,我需要做以下事情。我希望Thread2一直等到Thread1将Counter对象的计数加1。完成后,线程1通知线程2,然后线程1开始等待线程2将值递减1。然后,线程2启动并将值递减1,并再次通知线程1,然后线程2开始等待线程1。重复这个过程几次。

  • 我想做一个小练习来习惯等待/通知。我想做的是简单地启动一个线程,然后用等待让它进入睡眠状态,用通知唤醒它,多次。 我的代码是: 我希望这会是这样 相反,这样做: 所以。。。通知似乎没有唤醒打印机线程? 这不应该是一个死锁,因为通过等待,我释放了所有的锁,所以主服务器不应该有任何对打印机的锁,打印机应该能够唤醒并打印。 我做错了什么?

  • 我对通知方法的一点感到困惑。“notify() :它唤醒一个在同一对象上调用 wait() 的线程。因此,假设两个线程称为等待同一对象。那么当我调用通知时,将通知哪个线程?

  • 问题内容: 刚刚开始学习多线程。我在多个线程中有5个生产者和2个消费者。基本上,该程序将100个项目添加到队列中。当队列大小为100时,生产者将停止添加。我希望消费者在消费者从队列中删除所有项目时通知生产者,以便生产者可以再次开始添加。当前,生产者将等待,但永远不会收到消费者的通知。 制片人: 消费者: 主班 问题答案: 从oracle文档页面: BlockingQueue实现是线程安全的。所有排