2017-05-30 55 views
-1

我有以下一段代码,它从套接字读取一个字符串并对其进行处理。从套接字读取字符串后,我正在创建一个新线程来处理请求。这样,我可以有多个线程同时处理传入的请求。如何使用多线程从套接字读取请求

public void process(Socket socket) throws Exception { 
    while (true) { 
     String request = readFromSocket(socket); 
     new Thread(() -> { 
      try { 
       System.out.println(request); // [edit]: I had omitted this line before as I thought it would be irrelevant 
       response = processRequest(request); // <-- request could get modified 
      } catch (Exception e) { 
       // TODO: Log error and print stack-trace 
      } 
     }).start(); 
    } 
} 

这里的问题是,“请求”可能会在新线程开始处理它之前被修改。我是多线程的新手,我读了几个涵盖基础知识的网站。我仍然不确定如何解决这里的问题。

使用synchronized函数等待新线程完成处理请求将会终止多线程的目的。一旦我得到请求,我想将它发送到一个新的线程,以便它可以开始处理请求,而父线程可以读取下一个请求。

任何帮助我如何解决这个问题?谢谢!

[卢克的回答后编辑]

在我的情况下,请求将是一个文件名。您可以根据目录的大小获取多个请求。当我在一个文件较少的目录上尝试我的代码时,一切都很好。但是当我用一个有数千个文件的目录运行我的代码时,事情变得很奇怪。说readFromSocket后

,螺纹-1有要求X与和线程2具有请求Y.但是这里面的processRequest(),线程1开始处理请求Y.

+0

请学习如何使用线程池。 – Snickers3192

+0

已经降低了投票的人,请你澄清downvote的原因吗? – Anit

回答

1

有你的代码的各种问题。

正如你自己想的那样,一个线程P产生一些可能被消耗的东西,或者在P产生一个新结果之前没有被另一个线程消耗是不理想的。

因此,简单地存储像你这样的价值是不好的做法。合理的答案是:使用设计的数据结构以允许“一个线程放入某个东西,其他线程放出东西”;像ArrayBlockingQueue

然后:这是一个巨大的浪费时间为一个工作创建一个线程,然后把它扔掉。

取而代之:创建一个ExecutorService,并将任务转换为该服务。该服务可以基于线程的,重新使用;而不是扔掉。

3

这里的问题是,“请求”可能会在新线程开始处理它之前被修改。

这不是Java语言所允许的。

您不必担心request在被新线程处理之前被修改。因为,Thread.start()建立发生之间的关系request变量和processRequest(request)方法调用在新线程之间的关系。

当一个语句调用Thread.start时,与该语句具有happen-before关系的每个语句与新线程执行的每个语句之间都有一个happen-before关系。新线程可以看到导致创建新线程的代码的影响。

因此,此声明String request = readFromSocket(socket);发生在new Thread(...).start();之前以及新线程执行的任何代码。

另外String是不可变的,所以它一旦创建就不会改变。你很安全。

这就是说。您最好使用线程池来处理请求。

ExecutorService executorService = Executors.newFixedThreadPool(100); 

while (true) { 
    String request = readFromSocket(socket); 
    Runnable task =() -> { 
     processRequest(request); 
    }; 
    executorService.submit(task); 
} 

同样,调用ExecutorService.submit创建之前,无论发生什么情况,并在任务中的任何语句之间的之前发生关系。

+0

在我的方案中,请求将是一个文件名。您可以根据目录的大小获取多个请求。当我在一个文件较少的目录上尝试我的代码时,一切都很好。但是当我用一个有数千个文件的目录运行我的代码时,事情变得很奇怪。 在readFromSocket之后说,Thread-1有请求X并且Thread-2有请求Y.但是在processRequest()中,Thread-1开始处理请求Y. – Anit

+0

我编辑了我的代码和我的问题。你能看一下吗?谢谢! – Anit