Java Scala中有趣的线程行为

Java Scala中有趣的线程行为,java,multithreading,scala,Java,Multithreading,Scala,我正在做一些实验,试图在实践中理解线程。请看下面的代码段:它是一个主函数,它生成了一个线程来监听端口2020。该线程依次侦听该端口上的连接,并且每当客户端连接时,它都会生成另一个线程,该线程稍微休眠一点,然后写入套接字 class MyRunner(s:Socket,num:Int) extends Runnable{ val r = scala.util.Random def run(): Unit ={ if(num == 5 ) Thread.sleep(

我正在做一些实验,试图在实践中理解线程。请看下面的代码段:它是一个主函数,它生成了一个线程来监听端口2020。该线程依次侦听该端口上的连接,并且每当客户端连接时,它都会生成另一个线程,该线程稍微休眠一点,然后写入套接字

class MyRunner(s:Socket,num:Int) extends Runnable{

  val r = scala.util.Random

  def run(): Unit ={

    if(num == 5 )
      Thread.sleep(15000)
    else
      Thread.sleep(1000)

    s.getOutputStream.write(s"My number is  ${num}!  \n".getBytes)
    s.getOutputStream.close()
  }
}

// this thread opens a MyRunner thread on each new connection
class MyService extends Runnable{

  val serverSocket = new ServerSocket(2020)

  var num = 0

  def run():Unit = {
    while(true){
      val socket = serverSocket.accept()
      num += 1
      (new MyRunner(socket,num)).run()
    }
  }
}

// main function
object app {
  def main(args: Array[String]) {
    (new MyService).run
  }
}
现在我正在测试这个设置。我所做的是:打开两个终端窗口,在每个窗口上输入命令:

$ for i in `seq 1 5`; do netcat localhost 2020; done
问题是,当根据其中一个终端上的条件达到数字5时,另一个终端不会继续运行。两个客户端都会停止,直到15秒超时结束

我想知道我做错了什么,因为我认为使用线程的全部目的是让非阻塞应用程序能够为客户端提供服务,即使另一个客户端很忙


注意:我正在VirtualBox虚拟机上运行此程序,主机上总共有8个可用处理器,其中有4个可用处理器。

您的应用程序不会创建任何线程。创建如下线程:

Thread serverThread = new Thread(new MyService());
serverThread.start();
start方法是库提供的低级方法,当您想要创建新线程时,代码可以调用它

serverThread.run方法是代码为库提供的在新线程中调用的方法


额外提示:学习如何使用线程池,例如java.util.concurrent.ThreadPoolExecutor,而不是为每个客户端连接创建和销毁新线程。创建和销毁线程非常昂贵。

您的应用程序不会创建任何线程。创建如下线程:

Thread serverThread = new Thread(new MyService());
serverThread.start();
start方法是库提供的低级方法,当您想要创建新线程时,代码可以调用它

serverThread.run方法是代码为库提供的在新线程中调用的方法


额外提示:学习如何使用线程池,例如java.util.concurrent.ThreadPoolExecutor,而不是为每个客户端连接创建和销毁新线程。创建和销毁线程非常昂贵。

是的。我知道我误解了什么。谢谢。你有没有了解ThreadPoolExcecutor的好资料来源?@shondeslich,标准Java教程中的并发章节可能是一个很好的起点:是的。我知道我误解了什么。谢谢。您是否有了解ThreadPoolExcecutor的好资料来源?@shondeslich,标准Java教程中的并发章节可能是一个很好的起点: