Java线程行为

时间:2012-09-14 04:13:14

标签: java

我在互联网上看到了以下示例:

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”,但是另一个线程可能连续两次打印“1”吗?在这段代码中,我们至少有3个线程(1个主线程和2个线程创建)。我们可以想象调度程序运行1个线程:new Thread1()。start();然后在System.out.println(“1”)之后立即放弃;然后再次在Thread1()中运行另一个威胁.start();再次打印“1”?

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

  3. 在今天的计算机处理器中,我们主要拥有2个处理器,但我们仍然发现许多网络上的多线程程序使用超过2个线程!这个过程在编译时是不是变得沉重而缓慢?

3 个答案:

答案 0 :(得分:1)

1)无法保证线程的顺序。

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

3)具有两个内核的CPU只能同时运行两个线程,但大多数线程大部分时间都没有实际使用CPU,而是等待I / O或用户交互之类的事情。所以你可以通过拥有两个以上的线程获得很多(只有两个可以同时计算,但数百个可以同时等待)。看看node.js,这是最近流行的多线程编程替代方案,它可以实现并发请求的高吞吐量,同时只有一个执行线程。

答案 1 :(得分:0)

回答你的1/2问题: 虽然线程在内部运行并行代码,但线程的运行方法总是按顺序执行。

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

答案 2 :(得分:0)

  1. 没有。您没有以任何方式同步线程,因此确切的执行顺序将受调度程序的支配。鉴于你的线程是如何实现的,我看不出你怎么能用一个线程打印两次“1”(或“A”)。

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

  3. 这取决于线程正在做什么。如果每个线程都有足够的工作来将一个CPU核心加载到100%,那么是的,拥有比你的CPU核心更多的线程是毫无意义的。但是,这种情况很少发生。许多线程将花费大部分时间休眠,或等待I / O完成,或以其他方式处理不足以完全加载CPU核心的事情。在这种情况下,拥有更多CPU核心的线程没有任何问题。实际上,多线程在主流多核CPU之前就已存在,甚至在我们没有人拥有多个CPU核心的日子里,能够拥有多个线程仍然是非常有益的。