Java线程查询

时间:2010-01-22 07:14:01

标签: java multithreading

我正在处理涉及线程的java应用程序。所以我只是编写了一段代码来熟悉多个并发线程的执行情况

public class thready implements Runnable{
private int num;

public thready(int a) {
    this.num=a;
}
public void run() {
  System.out.println("This is thread num"+num);
  for (int i=num;i<100;i++)
  {
      System.out.println(i);
  }
}
public static void main(String [] args)
{
    Runnable runnable =new thready(1);
    Runnable run= new thready(2);
    Thread t1=new Thread(runnable);
    Thread t2=new Thread(run);
    t1.start();
    t2.start();
}}

现在从这段代码的输出中,我认为在任何时间点只有一个线程正在执行,执行似乎在线程之间交替。现在我想知道我对情况的理解是否正确。如果它是我想知道是否有任何方式我可以让两个线程同时执行,因为我希望将这种情况合并到我希望编写同时侦听2的tcp / ip套接字侦听器的情况港口,同时。而这种情况不能有任何停机时间。 任何建议/意见都会有很大的帮助。

干杯

10 个答案:

答案 0 :(得分:5)

您的机器有多少个处理器?如果您有多个核心,则两个线程应该同时运行。但是,控制台输出可能会被缓冲,并且需要在内部锁定 - 这可能是您所看到的效果。

测试这个的最简单方法是让线程做一些真正的工作,并为它们计时。首先按顺序运行这两个任务,然后在两个不同的线程上并行运行它们。如果这两个任务根本不相互交互(包括“隐藏”交互,如控制台),那么你应该看到使用两个线程的大致 2x性能提升 - 如果你有两个核心或更多

正如Thilo所说,无论如何,这可能与您的真实场景无关。即使是单线程系统仍然可以监听两个套接字,尽管每个套接字更容易让一个线程负责。在你正在收听套接字的大多数情况下,你会花费大量时间等待更多数据 - 在这种情况下,你是否拥有多个核心并不重要。

编辑:当你在一台具有单核心的机器上运行时(假设没有超线程),你一次只执行一个线程,几乎就是定义。调度程序将确保两个线程都获得CPU时间,但它们基本上必须轮流使用。

答案 1 :(得分:1)

如果您有多个CPU,则两个线程可以同时运行。即使您只有一个CPU,只要其中一个线程等待I / O,另一个线程就可以使用CPU。 JVM很可能也会尝试公平地消除CPU时间片。因此,出于所有实际目的(除非它们都使用CPU),您的线程将同时运行(如:在给定的秒内,每个线程都可以访问CPU)。

因此,即使使用单个CPU,也可以让两个线程分别监听TCP / IP套接字。

答案 2 :(得分:0)

让线程睡在println语句之间。你执行的内容太快,无法看到效果。

答案 3 :(得分:0)

线程只是一种虚拟化CPU的方法,因此它可以被多个应用程序/线程同时使用。但由于CPU一次只能执行一个程序,因此操作系统可以非常快速地在不同的线程/进程之间切换。

如果你的CPU只有一个核心(不考虑超线程),那么你的观察,即一次只执行一个线程,是完全正确的。并且以任何其他方式都是不可能的,你没有做错任何事。

答案 4 :(得分:0)

如果每个线程占用的CPU量都少于一个,那么它们似乎会按顺序运行。连续打印100个数字可能不足以耗尽整个量程,因此您可能会看到线程的顺序运行。

同样,和其他人一样,你可能至少有两个CPU或一个超线程CPU。最后一个纯粹的单核系统是在十年前生产出来的,因此你的线程不可能并行运行。

尝试增加您执行的处理量,您可能会看到输出混合在一起。请注意,当你这样做时,System.out.println不是线程安全的,据我所知。你会得到一个线程来打断另一个中线的输出。

答案 5 :(得分:0)

它们同时运行,它们不能同时使用输出流。

run - 方法替换为:

public void run() {
   for (int i=num;i<100;i++) {
      try {
         Thread.sleep(100);
         System.out.println("Thread " + num + ": " + i);
      } catch (InterruptedException e) {
         e.printStackTrace();
      }  
   }
}

答案 6 :(得分:0)

如果每秒收到许多消息并处理每个数据需要几毫秒到几秒,那么每条消息启动一个线程并不是一个好主意。最终产生的线程数量受底层操作系统的限制。您可能会遇到线程外错误或类似错误。

Java 5引入了线程池框架,您可以在其中分配固定数量的线程并提交作业(Runnable的实例)。此框架将在池中的一个可用线程中运行该作业。由于没有进行太多的上下文切换,因此效率更高。我写了一篇博客文章来启动这个框架。

http://dudefrommangalore.blogspot.com/2010/01/concurrency-in-java.html

干杯, - baliga

答案 7 :(得分:0)

对于有关侦听2个端口的问题,客户端必须向其中一个端口发送消息。但是,由于两个端口都打开以接受单个JVM中的连接,因此如果JVM无法使用2个端口,则无法为您提供高可用性。

用于编写侦听端口的服务器的常用模式是让一个线程侦听端口。一旦数据到达,就会产生另一个线程,将内容以及客户端套接字移交给新生成的线程并继续接受新消息。

另一种模式是让多个线程侦听同一个套接字。当客户端连接时,连接到其中一个线程。

答案 8 :(得分:0)

这可能出错的两种方式:

  • System.out.println()可以使用缓冲区,你应该调用flush()将它带到屏幕上。
  • 必须有一些同步 构建到System.out对象或 你不能用它 多线程应用程序没有 弄乱输出,所以它是 可能是一个线程持有锁 在大多数情况下,让其他线程等待。尝试在一个线程中使用System.out,在另一个线程中使用Sytem.err。

答案 9 :(得分:-1)

开始阅读多任务处理和多道程序设计。 http://en.wikipedia.org/wiki/Computer_multitasking