Java 监视阻止操作

Java 监视阻止操作,java,multithreading,race-condition,Java,Multithreading,Race Condition,我正在尝试编写一个线程来监视阻塞操作需要多长时间。例如,我有一个如下的阻塞动作: class BlockingThread extends Thread{ public volatile boolean success = false; public volatile long startedTime = 0; public void run(){ startedTime = System.currentTimeMillis(); succe

我正在尝试编写一个线程来监视阻塞操作需要多长时间。例如,我有一个如下的阻塞动作:

class BlockingThread extends Thread{

    public volatile boolean success = false;
    public volatile long startedTime = 0;

    public void run(){

      startedTime = System.currentTimeMillis();
      success = doBlockingAction(); //no idea how long this action will take
    }

}
我想要另一个线程,如果阻塞操作花费的时间太长,它基本上会调用“timeout”函数:

class MonitorThread extends Thread{

    public void run(){
      while(System.currentTimeMillis() - blockingThread.startedTime > TIMEOUT_DURATION)
      {
         ..keep waiting until the time runs out..
      }

      if(!blockingThread.success){
         listener.timeout();
         //Took too long.
      }
    }

}
当我在MonitorThread中测量时间时,我很难理解如何确保BlockingThread当前实际处于阻塞操作中

如果我这样做

Thread blockingThread = new BlockingThread();
blockingThread.start();
Thread monitorThread = new MonitorThread();
monitorThread.start();

不能保证其中一个线程在另一个线程之前开始运行代码,因此我目前无法知道超时线程是否正确地测量了阻塞操作的时间。我假设答案与锁定和等待有关,但我无法理解。

在blockingThread.startingTime初始化之前,您可能需要循环几次

class MonitorThread extends Thread{

    public void run(){
        boolean weWantToKeepRunning = true;

        // here is your new event loop
        while(weWantToKeepRunning){

            if (blockingThread.startedTime != 0) && (System.currentTimeMillis() - blockingThread.startedTime > TIMEOUT_DURATION)&& (!blockingThread.success){

                listener.timeout();   // too long
                weWantToKeepRunning = false;  // quit this loop

            }
        }
    }
}

我可以建议您使用类重写代码。 这个类有一个很好的方法
waittermination()
,我想这正是您所需要的

编辑:

这是您的BlockingThread(运行10秒)和Monitor(等待5秒):

package sample.threadexecutor;

import java.text.SimpleDateFormat;
import java.util.Date;

public class BlockingThread implements Runnable{

    public boolean succsess = false;
    @Override
    public void run() {
        SimpleDateFormat df = new SimpleDateFormat("HH:mm:ss.SSS");
        System.out.println(df.format(new Date())  + " start");
        try {
            Thread.sleep(10000L);
        } catch (InterruptedException e) {
            System.out.println(df.format(new Date())  + " interrupted");
            succsess = false;
            return;
        }
        System.out.println(df.format(new Date())  + " end");
        succsess = true;
    }
}
和执行器的主要功能:

package sample.threadexecutor;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class main {

    public static void main(String[] args) {
        SimpleDateFormat df = new SimpleDateFormat("HH:mm:ss.SSS");
        ExecutorService service= Executors.newSingleThreadExecutor();
        service.submit(new BlockingThread());
        try {
            service.shutdown();
            if(service.awaitTermination(5, TimeUnit.SECONDS)){
                System.out.println(df.format(new Date())  + " execution completed");
            }else{
                System.out.println(df.format(new Date())  + " execution timeout");
            }
        } catch (InterruptedException e) {
            System.out.println(df.format(new Date())  + " monitoring interrupted");
        }

    }
}
和输出:

22:28:37.005 start
22:28:42.006 execution timeout
22:28:47.006 end
如果我们将超时设置为20秒,则输出:

22:30:20.210 start
22:30:30.213 end
22:30:30.214 execution completed

doBlockingAction到底做什么?JavaAPI中的大多数阻塞操作都有允许设置超时的变体。使用超时变量是最准确的方法。

我希望您指的是
class BlockingThread
class MonitorThread
。有一种方法专门用于超时方法执行。这可能会有帮助。@Jeffrey哈哈,哎呀。感谢您的帮助。我不明白为什么您不能简单地执行
while(blockingThread.startedTime==0 | | System.currentTimeMillis()-blockingThread.startedTime>TIMEOUT\u DURATION)
@AdrianShum,因为JVM可以随时在线程之间切换。因此startedTime可以设置为当前时间,然后在执行线程的下一行(阻塞操作行)之前,JVM开始运行一个新线程。或者至少,我是这样理解的。对不起,我不明白这是如何解决我的问题的。你能说得更具体些吗?