java - 监视阻塞操作

标签 java multithreading race-condition

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

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
    }

}

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

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();

无法保证其中一个线程实际上会先于另一个线程开始运行代码,因此我目前无法知道我的超时线程是否真的在正确测量阻塞操作的时间。我认为答案与锁定和等待有关,但我想不通。

最佳答案

我可以建议您使用类 java.util.concurrent.ThreadPoolExecutor 重写代码. 这个类有很好的方法 awaitTermination(),我想这正是您需要的。

编辑:

这是你的 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

关于java - 监视阻塞操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12207495/

相关文章:

c++ - Linux 套接字和线程

char 数组上的 C++ 内存模型和竞争条件

git - 本地 Git 存储库是线程安全的吗?

java - 如何从 DAO 迭代多个数据

java - 用于组合两个 Maybe 的 RxJava2 习语

java - RecyclerView notifyItemChanged(position) 使应用程序崩溃并且没有使用 notifyDataSetChanged() 的动画

multithreading - 这是比赛条件吗?

java - 为 cordova (Android) 开发插件时无法找到源 java 类

c - 如何获取函数_beginthread的第一个参数_StartAddress的返回值

java - 返回结果时保持提交任务的顺序