Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/373.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 如何使一个线程连接到另一个线程,但只等待n秒的CPU时间?_Java_Multithreading_Unit Testing_Concurrency_Performance - Fatal编程技术网

Java 如何使一个线程连接到另一个线程,但只等待n秒的CPU时间?

Java 如何使一个线程连接到另一个线程,但只等待n秒的CPU时间?,java,multithreading,unit-testing,concurrency,performance,Java,Multithreading,Unit Testing,Concurrency,Performance,otherThread.join(time)以毫秒为单位显示等待时间。我希望在实际CPU时间内等待时间,以便在应用程序中获得一致的行为 我已经快速查看了ThreadMXBean,但这似乎并不是我想要的(它告诉我线程的实际CPU时间,但没有提供等待一段时间过去的便捷方式)。围绕sleep()的繁忙循环可能会起作用,但似乎效率极低 我还考虑过使用另一个线程并等待一个条件,但我不确定这将如何工作。主线程将执行:myCondition.await(),其中另一个线程将在otherThread使用时间时切

otherThread.join(time)
以毫秒为单位显示等待时间。我希望在实际CPU时间内等待
时间
,以便在应用程序中获得一致的行为

我已经快速查看了
ThreadMXBean
,但这似乎并不是我想要的(它告诉我线程的实际CPU时间,但没有提供等待一段时间过去的便捷方式)。围绕
sleep()
的繁忙循环可能会起作用,但似乎效率极低

我还考虑过使用另一个线程并等待一个
条件
,但我不确定这将如何工作。主线程将执行:
myCondition.await()
,其中另一个线程将在
otherThread
使用
时间时切换
myCondition
。同样,这看起来很复杂,可能仍然需要控制线程有一个繁忙的循环

编辑:我这样做是为了评分脚本。这意味着,如果学生处于无限循环中,我需要有一种超时方法,并且需要公平。我一直在使用JUnit对学生进行测试,但这与超时有着相同的问题:如果同一个(低效的)提交被多次运行,它可能会得到不同的分数,这取决于当时机器上运行的其他作业(这对于小组工作来说是一个真正的问题)


但这也是普通单元测试的一个问题-通过使用时钟时间而不是CPU时间JUnit会得到不一致的测试结果?

我建议一次运行一个JVM测试,并使用
时间
(有关详细信息,请参阅)确定实际使用的CPU时间。如果时间太长的话就打断它。。。您可能可以使用shell脚本来完成这一点,或者只允许进程运行到完成,并根据实际花费的时间进行分级。

我建议一次运行一个JVM测试,并使用
时间
(有关详细信息,请参阅)来确定实际使用的CPU时间。如果时间太长的话就打断它。。。您可能可以使用shell脚本来完成这一点,或者只允许流程运行到完成,并根据实际花费的时间进行分级。

不会发生。定时的
join()
基于墙上的时钟时间,这意味着如果线程尚未退出,则可以设置硬件计时器以提供x秒后的异步中断。由于无法预先知道线程将使用多少CPU,因此无法在达到某个边界时安排中断。当一个进程自愿或强制地产生它的时间片时,CPU时间就被考虑进去了,所以无论如何也没有办法得到确切的数字

您能得到的最接近的结果是每隔一段时间轮询CPU利用率,并在超出限制的线程上调用
interrupt()
。(仔细研究它的语义,因为中断线程不一定会立即停止线程。)如果您只关心线程是否占用了x秒以上的CPU时间,那么延迟检查得到的结果(如kx,其中k>1)就无关紧要了。它们仍然大于x,这足以让你知道你的候选人超过了极限


如果您在Unix-y系统上,可以做的一件事是将整个分配作为一个进程运行,并使用
ulimit
将允许的CPU量限制在某个值上,并为JVM启动和程序加载添加合理的CPU量。

不会发生。定时的
join()
基于墙上的时钟时间,这意味着如果线程尚未退出,则可以设置硬件计时器以提供x秒后的异步中断。由于无法预先知道线程将使用多少CPU,因此无法在达到某个边界时安排中断。当一个进程自愿或强制地产生它的时间片时,CPU时间就被考虑进去了,所以无论如何也没有办法得到确切的数字

您能得到的最接近的结果是每隔一段时间轮询CPU利用率,并在超出限制的线程上调用
interrupt()
。(仔细研究它的语义,因为中断线程不一定会立即停止线程。)如果您只关心线程是否占用了x秒以上的CPU时间,那么延迟检查得到的结果(如kx,其中k>1)就无关紧要了。它们仍然大于x,这足以让你知道你的候选人超过了极限


如果您在Unix-y系统上,您可以做的一件事是将整个分配作为一个进程运行,并使用
ulimit
将允许的CPU量限制在某个值上,并为JVM启动和程序加载添加合理的CPU量。

想想您的要求:您希望线程阻塞(而不是使用CPU时间)直到它使用了指定的CPU时间。这没有道理


我怀疑如果您的线程在另一个线程使用指定的CPU时间之前阻塞,您真正想要的是什么。这是不容易提供的,可能是因为它很少有用,可能会导致代码性能不佳。

想想你的要求:你希望线程阻塞(不使用CPU时间),直到它使用了指定的CPU时间。这没有道理


我怀疑如果您的线程在另一个线程使用指定的CPU时间之前阻塞,您真正想要的是什么。这是不容易提供的,可能是因为它很少有用,可能会导致您的代码性能不佳。

我认为如果您将thread.join()/interrupt()策略(用于超时错误代码(无限循环))和测试read calling back cpu time结合起来,您就会得到想要的结果,如果我不知道的话
public class GradingThread extends Thread {
    private Thread testThread;
    private long elapsedClockTime=-1;
    public GradingThread(TestingThread testThread){
        this.testThread = testThread;
        testThread.setGradingThread(this);
    }
    public void setElapsed(long elapsedClockTime){
        this.elapsedClockTime = elapsedClockTime;
    }
    public void run(){
        System.out.println("GradingThread ID="+Thread.currentThread().getId());
        try{
        testThread.start();
        testThread.join(5000);
        testThread.interrupt();
        }catch(Exception e){e.printStackTrace();}
        if(elapsedClockTime==-1){
            System.out.println("Student program timedout (more than 5000 clock seconds)");
        }else{
            System.out.println("Student program elapsed cpu time = "+(elapsedClockTime)/1000000+"ms");
        }
    }
    public static void main(String[] args) {
        (new GradingThread(new TestingThread())).start();
    }
}
public class TestingThread extends Thread {
    private GradingThread gradingThread;
    public void setGradingThread(GradingThread thread){
        gradingThread = thread;
    }
    public void run(){
        StudentProgram sp = new StudentProgram();
        System.out.println("TestingThrad ID="+Thread.currentThread().getId());
        long scpu = getCpuTime();
            sp.takeLessThan5WallSecondsToRun(); //try calling infiniteLoop() too.
        long ecpu = getCpuTime();
        gradingThread.setElapsed(ecpu - scpu);
    }
    /** Get CPU time in nanoseconds. */
    public long getCpuTime( ) {
        ThreadMXBean bean = ManagementFactory.getThreadMXBean( );
        if ( ! bean.isCurrentThreadCpuTimeSupported())
            return -1L;
        long time = bean.getThreadCpuTime(Thread.currentThread().getId());       
        return time;
    }
}//end of TestingThread.
class StudentProgram {
    public void infiniteLoop(){
        while(true);
    }
    public int takeLessThan5WallSecondsToRun(){
        int total=0;
        while(total < Integer.MAX_VALUE) total++;
        return total;   
    }
}//end of StudentProgram.