什么';非GUI Java应用程序的正确后台进程行为是什么?

什么';非GUI Java应用程序的正确后台进程行为是什么?,java,background,Java,Background,Java命令行应用程序在不占用资源的情况下进行后台工作的正确方法是什么?它应该在循环中使用sleep(),还是有更优雅/高效的方法?首先要确保只使用这些资源,而不使用其他对象(这样它们就会被垃圾收集) 在单线程应用程序中放置sleep()只会停止当前线程。如果您试图在后台完成数据处理,而信息仍然需要呈现给用户,那么最好将后台处理放在一个单独的线程中。如果没有工作要做,我只会使用sleep()。例如,如果您正在定期轮询一个任务队列,但那里什么都没有,请先休眠一段时间,然后再次检查,等等 如果您只是

Java命令行应用程序在不占用资源的情况下进行后台工作的正确方法是什么?它应该在循环中使用sleep(),还是有更优雅/高效的方法?

首先要确保只使用这些资源,而不使用其他对象(这样它们就会被垃圾收集)

在单线程应用程序中放置sleep()只会停止当前线程。如果您试图在后台完成数据处理,而信息仍然需要呈现给用户,那么最好将后台处理放在一个单独的线程中。

如果没有工作要做,我只会使用sleep()。例如,如果您正在定期轮询一个任务队列,但那里什么都没有,请先休眠一段时间,然后再次检查,等等

如果您只是想确保不占用CPU,但仍在进行实际工作,那么可以定期调用Thread.yield()。这将放弃对CPU的控制,让其他线程运行,但不会让您进入睡眠状态。如果其他进程不需要CPU,您将获得控制权并继续执行您的工作

您还可以将线程设置为低优先级: myThread.setPriority(Thread.MIN_PRIORITY)

正如以实玛利所说,不要在你的主线中这样做。而是创建一个“工作线程”。这样,您的UI(GUI或CLI)仍能响应。

一些启发:

  • 不要试图在应用程序中做出调度决策。操作系统的调度程序比您的要好得多。让它做它的工作
  • 如果你不必投票,就不要投票。例如,与其睡n秒,然后醒来检查未阻塞的套接字,不如阻塞套接字。第二种策略更适合操作系统的调度程序
  • 如果不需要的话,不要使用巨大的堆,尽量不要一次分配大量内存。抖动应用程序往往会对系统性能产生负面影响
  • 始终使用缓冲I/O。如果您认为需要非缓冲I/O,请绝对确保您是正确的。(你可能错了。)
  • 不要产生很多线程。线程出人意料地昂贵;超过某一点,更多线程将降低应用程序的性能。如果您有大量工作要同时完成,请学习并使用
    java.util.concurrent

当然,这只是一个初步列表…

有几种方法。我会用你的服务。。。例如:

ExecutorService service = Executors.newCachedThreadPool();

Callable<Result> task = new Callable<Result>() {
    public Result call() throws Exception {
        // code which will be run on background thread
    }
};

Future<Result> future = service.submit(task);

// Next line wait until background task is complete
// without killing CPU. Of course, you can do something
// different here and check your 'future' later.
//
// Note also that future.get() may throw various exceptions too,
// you'll need to handle them properly

Result resultFromBackgroundThread = future.get();
ExecutorService service=Executors.newCachedThreadPool();
可调用任务=新的可调用任务(){
公共结果调用()引发异常{
//将在后台线程上运行的代码
}
};
Future=service.submit(任务);
//下一行等待后台任务完成
//在不破坏CPU的情况下。当然,你可以做点什么
//这里不同,稍后检查您的“未来”。
//
//还要注意,future.get()也可能引发各种异常,
//你需要妥善处理它们
Result resultFromBackgroundThread=future.get();

这是Java 5代码,ExecutorService、Callable、Future和类似的代码都在
Java.util.concurrent
包中。

这是一个挑剔的问题,但我相信设置线程优先级只会设置JVM中线程的优先级,而不会设置OS级线程的优先级。如果你担心在JVM之外占用资源,你仍然需要在OS中设置进程优先级。@贾里德:我认为你是对的,我不认为这是一个挑剔。线程需要操作系统支持,并且具有特定于操作系统的行为。在早期版本的Java for Solaris上,有一种称为绿色线程的东西,它基本上是一种解决操作系统线程能力不足的方法。这并不完全正确。如果您有一个任务队列,您应该使用BlockingQueue的实例,该实例可以正确地处理等待/通知,而无需求助于睡眠。当你睡觉的时候,你很可能会影响吞吐量,因为新任务就在你睡觉的时候到达。@Dave:我同意阻塞比睡眠(如果有)好。这样,当工作到来时,你会立即醒来。我想到的情况是,当“任务”作为文件在特定文件夹中接收时。如果是那样的话,我想你得睡觉了。