我正在开发ODL应用程序,并已从我的主要功能中安排了一个任务(MonitorLinksTask),以便监视拓扑的所有链接中的延迟。我想为每个链接发送一个数据包,并且在控制器接收到它之后,为下一个链接发送下一个数据包。 main中的代码是:

Timer time = new Timer();
MonitorLinksTask monitorLinksTask = new MonitorLinksTask();
time.schedule(monitorLinksTask, 0, 5000);


MonitorLinksTask是:

public class MonitorLinksTask extends TimerTask{

    static boolean flag = false;

    public void run() {

        for (DomainLink link : linkList) {
            sendPacket();
            while (flag == false){
                 //waits until it gets notified that the sent packet has been received
            }
            System.out.println("Sending next packet.");
            System.out.println("----------");
            flag = false;
        }

    }
}


哪里:

private void sendPacket(){
    Packet packet;
    PacketProcessingService packetProcessingService = ... ;
    // .... fill the packet ....
    System.out.println("Packet transmitted at time " + System.currentTimeMillis());
    packetProcessingService.transmitPacket(packet);
}


到目前为止,任务每5秒钟运行一次,并调用该函数为每个链接发送一个数据包,以计算图中每个链接的单程延迟。

我创建了一个监听器,以便每次控制器接收到一个数据包时,它都会通知MonitorLinksTask它已接收到该数据包,然后MonitorLinksTask可以发送下一个数据包。

public void onPacketReceived(PacketReceived packetReceived) {

    System.out.println("Packet received at time " + System.currentTimeMillis());
    MonitorLinksTask.flag = true;

}


但是,我的程序对于MonitorLinksTask的前两个执行是正确的,而第三个执行则停止了。具有两个链接的案例的示例输出:

Packet transmitted at time 1549333576093
Packet received at time 1549333576096
Sending next packet.
Packet transmitted at time 1549333576111
Packet received at time 1549333576115
Sending next packet.
----------
Packet transmitted at time 1549333576122
Packet received at time 1549333576124
Sending next packet.
Packet transmitted at time 1549333576128
Packet received at time 1549333576129
Sending next packet.
----------
Packet transmitted at time 1549333576136
Packet received at time 1549333576140


有任何想法吗?

最佳答案

假设所有这些都发生在同一个JVM中:


Thread.currentThread().getName()添加到日志中,以便在执行是多线程还是单线程时从日志中清除;
如果以前是,请尝试在volatile中添加flag修饰符。


由于上述内容有助于解决您的问题,因此很显然,这是由于线程(TimerTask线程和您的应用程序线程)之间缺少可见性更新引起的。让我建议Oracle Concurrency以进一步了解Java多线程。您提到的特定问题是here

09-13 08:13