Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ionic-framework/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java TimerTask中的同步失败_Java_Synchronization - Fatal编程技术网

Java TimerTask中的同步失败

Java TimerTask中的同步失败,java,synchronization,Java,Synchronization,我正在开发一个ODL应用程序,并已从我的主功能计划了一项任务(MonitorLinksTask),以监控拓扑结构的所有链路中的延迟我希望每个链路发送一个数据包,控制器接收到数据包后,为下一个链路发送下一个数据包。主中的代码是: Timer time = new Timer(); MonitorLinksTask monitorLinksTask = new MonitorLinksTask(); time.schedule(monitorLinksTask, 0, 5000); public

我正在开发一个ODL应用程序,并已从我的主功能计划了一项任务(
MonitorLinksTask
),以监控拓扑结构的所有链路中的延迟我希望每个链路发送一个数据包,控制器接收到数据包后,为下一个链路发送下一个数据包。主中的代码是:

Timer time = new Timer();
MonitorLinksTask monitorLinksTask = new MonitorLinksTask();
time.schedule(monitorLinksTask, 0, 5000);
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;
        }

    }
}
类别
MonitorLinksTask
为:

Timer time = new Timer();
MonitorLinksTask monitorLinksTask = new MonitorLinksTask();
time.schedule(monitorLinksTask, 0, 5000);
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秒运行一次,并调用函数以发送每个链路的数据包,以便计算图中每个链路的单程延迟

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

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
    修饰符添加到
    标志

  • 由于以上帮助解决了您的问题,很明显,这是由于线程之间缺乏可见性更新(
    TimerTask
    thread和您的应用程序线程)造成的。我建议您进一步了解Java多线程。这里提到了您的具体问题。

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

  • Thread.currentThread().getName()
    添加到日志中,以便在执行为多线程或单线程时从日志中清除
  • 如果是前者,请尝试将
    volatile
    修饰符添加到
    标志

  • 由于以上帮助解决了您的问题,很明显,这是由于线程之间缺乏可见性更新(
    TimerTask
    thread和您的应用程序线程)造成的。我建议您进一步了解Java多线程。提到了您的具体问题。

    假设所有这些都发生在同一个JVM中:1)将
    Thread.currentThread().getName()
    添加到日志中,以便在多线程或单线程执行时从日志中清除;2) 如果是前者,请尝试将
    volatile
    修饰符添加到
    flag
    @victorsorkin谢谢!!这个问题现在似乎已经解决了。您可以将您的评论作为答案,以便我接受它。假设所有这些都发生在同一个JVM中:1)将
    Thread.currentThread().getName()
    添加到日志中,以便在执行是多线程还是单线程时从日志中清除;2) 如果是前者,请尝试将
    volatile
    修饰符添加到
    flag
    @victorsorkin谢谢!!这个问题现在似乎已经解决了。你可以回答我的意见,这样我就接受了。