2

我正在阅读多线程:http://www.ntu.edu.sg/home/ehchua/programming/java/j5e_multithreading.html

它建议(不要求)您在单核 CPU 的 CPU 密集型任务中添加一个Thread.sleep(10),并且通过这样做有效地为 CPU 提供了额外的时间来更新它拥有的所有其他线程(最重要的是,UI程序,我正在努力改进)。

这对我来说没有任何意义。虽然我的程序没有响应,但我的计算机的其余部分运行良好,我相信是 Windows 为每个程序分配了 CPU 时间。

不管怎样,这是个好建议吗?如果是这样,我是在说“这是其他线程的 10 毫秒奖励”,还是可以Thread.sleep(0)正常工作?

4

2 回答 2

4

我认为对于 2004 年的一篇文章(因为它引用了 JDK5 的新特性)和第一个双核处理器在 2006 年出现了一个很好的建议。当你有单核并且长时间运行的进程时,线程让步会让你的系统更具响应性.

如果您的应用程序加载所有可用内核,我认为今天可以应用相同的技术。对于文章中的示例,我认为这个长时间运行的操作可能只是被放到一个线程池中而没有产生。

更新

线程让出非常依赖于环境:yield()、sleep(0)、wait(0,1) 和 parkNanos(1)

如果你想等待一小段时间,你不能假设所有这些方法都做同样的事情,平台之间也不会是一样的。

于 2013-11-10T08:30:51.483 回答
2

这显然是一个老建议,因为在 Windows 上休眠会导致主线程暂停并处理后台线程。您可以将旧线程概念想象为队列,并且只有前端线程获得处理时间。一旦该线程被搁置(在 Windows 上甚至 sleep(1) 就足够了),当前线程将被置于队列的末尾,其他线程将被处理。

然而,现代操作系统处理这个完全不同的问题,这个建议今天是多线程实现错误的标志。Java 为您提供了设置线程优先级的选项,并允许您轻松使用后台线程进行繁重的处理。今天你会像这样实现它:

首先,我们需要一个用于低优先级线程的 ThreadFactory:

public class PriorityThreadFactory implements ThreadFactory {

  protected final ThreadGroup allThreads;

  public PriorityThreadFactory(final String name, final int priority, final boolean daemon) {
    this.allThreads = new ThreadGroup(name);
    this.allThreads.setMaxPriority(priority);
    this.allThreads.setDaemon(daemon);
  }

  @Override
  public Thread newThread(final Runnable r) {
    return new Thread(this.allThreads, r);
  }
}

然后我们创建一个 ExecutorService 并将优先级设置为Thread.MIN_PRIORITY

final PriorityThreadFactory threadFactory = new PriorityThreadFactory("workers", Thread.MIN_PRIORITY, true);
final ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors(), threadFactory);

最后,我们可以提交任意数量的任务,它们将在后台处理,不会阻塞像 UI-Thread 这样的重要线程。

executor.submit(new MyWorkerTask());
于 2013-11-10T10:05:22.920 回答