1

我在网上看到了下面的例子:

public class TwoThreads {
public static class Thread1 extends Thread {
    public void run() {
        System.out.println("A");
        System.out.println("B");
    }
}
public static class Thread2 extends Thread {
    public void run() {
        System.out.println("1");
        System.out.println("2");
    }
}
public static void main(String[] args) {
    new Thread1().start();
    new Thread2().start();
}

}


我的问题是:

  1. 保证“A”会在“B”之前打印,“1”会在“2”之前打印,但是“1”是否有可能被另一个线程连续打印两次?在这段代码中,我们至少有 3 个线程(1 个主线程和 2 个创建线程)。我们可以想象调度器运行 1 个线程:new Thread1().start(); 然后在 System.out.println("1"); 之后立即放弃 然后再次在 Thread1().start() 中运行另一个威胁;再次打印“1”?

  2. 我正在使用 NetBeans IDE,似乎运行这样的程序总是会导致相同的第一个结果,所以似乎有一些缓存。据我了解,您通过声明 volatile 变量来处理这个问题,可以在这里完成吗,如何?如果不是,那么缓存的解决方案是什么?

  3. 在今天的计算机处理器中,我们大多有2个处理器,但我们仍然发现网上很多多线程程序都使用2个以上的线程!这个过程在编译方面不是变得繁重而缓慢吗?

4

3 回答 3

1

1) 无法保证线程将按什么顺序进行。

2) 但是,顺序也不是随机的。因此,如果您在相同(或非常相似)的条件下运行程序,它可能会产生相同的线程交错。如果您需要某种行为(包括随机行为),您需要自己同步事物。

3) 一个有两个核心的 CPU 只能同时运行两个线程,但大多数线程大部分时间都不是真正使用 CPU,而是等待 I/O 或用户交互之类的事情。因此,您可以从拥有两个以上的线程中获得很多收益(只有两个可以同时计算,但数百个可以同时等待)。看看 node.js,它是最近流行的多线程编程替代方案,它在只有一个执行线程的同时实现了并发请求的高吞吐量。

于 2012-09-14T04:17:50.390 回答
0

回答您的 1/2 问题:虽然线程在线程的 run 方法中运行并行代码,但始终按顺序执行。

回答你的 3 个问题,你可以最好地调整你的。应用程序如果处理器数 = 线程数,但这不是一个完整的事实,因为如果线程正在等待某个阻塞操作,那么它将导致未优化的性能,因为在此期间另一个线程可以运行。

于 2012-09-14T04:20:27.067 回答
0
  1. 不。您没有以任何方式同步您的线程,因此确切的执行顺序将由调度程序决定。鉴于您的线程是如何实现的,我看不出您如何能够让单个线程打印两次“1”(或“A”)。

  2. 什么缓存?以及什么变量?您的示例代码没有变量,因此不适合与volatile关键字一起使用。在运行该程序的给定机器上,很可能总是会产生相同的结果。如 #1 中所述,您受调度程序的支配。如果调度程序始终以相同的方式运行,您将始终得到相同的结果。缓存与它无关。

  3. 这取决于线程在做什么。如果每个线程都有足够的工作将一个 CPU 核心加载到 100%,那么是的,拥有比 CPU 核心更多的线程是没有意义的。但是,这种情况很少见。许多线程将大部分时间都花在休眠或等待 I/O 完成,或以其他方式执行要求不足以完全加载 CPU 内核的事情。在这种情况下,拥有比 CPU 内核更多的线程没有任何问题。事实上,多线程早于主流的多核 CPU,即使在我们没有超过一个 CPU 核心的时代,拥有多个线程仍然是非常有益的。

于 2012-09-14T04:21:24.683 回答