【发布时间】:2017-10-18 02:42:41
【问题描述】:
我正在使用 Java 中的 HttpSevlet 构建一个 Web 服务器。我创建了一个名为 BaseApi 的 ABSTRACT 类,它扩展了 HttpSevlet 并用作父类。
每次调用 BaseApi 的 doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException。一个新的 BaseRequest 被实例化。 BaseRequest 只是我创建的另一个类,它是 BaseApi 的成员。
public abstract class BaseApi extends HttpServlet
{
private static final long serialVersionUID = 6333682258528494467L;
protected BaseRequest request;
}
然后我有一个子类,DeviceList 扩展了 BaseApi,DeviceListRequest 扩展了 BaseRequest
public class DeviceList extends BaseApi
public class DeviceListRequest extends BaseRequest
问题是这样的。每次调用 DeviceList 的 doGet 方法时,我认为会创建一个新线程。嗯,我发出了 2 个并发请求,日志是这样的。
[2017-10-18 02:06:39,760] INFO Thread:Thread[http-nio-8080-exec-8,5,main] Instance:server.request.DeviceListRequest@2f15bbce retCode:-3
[2017-10-18 02:06:39,761] INFO Thread:Thread[http-nio-8080-exec-7,5,main] Instance:server.request.DeviceListRequest@5343acea retCode:-3
好吧,不要介意 retCode 的事情,只关注 Thread: 和 Instance:。我不确定Thread[http-nio-8080-exec-8,5,main] 和Thread[http-nio-8080-exec-7,5,main] 是否是两个不同的线程。因为那里有一个词MAIN。而且我不知道是否可以有两个主线程。或者,如果这确实是主线程。
所以,根据日志。我认为创建了两个线程和 DeviceListRequest 的两个不同实例创建了 DeviceListRequest@2f15bbce 和 DeviceListRequest@5343acea。
现在,随着代码继续运行,我注意到线程开始交替访问两个 DeviceListRequest。这是其余的日志
[2017-10-18 02:06:39,760] INFO Thread:Thread[http-nio-8080-exec-8,5,main] Instance:server.request.DeviceListRequest@2f15bbce retCode:-3
[2017-10-18 02:06:39,761] INFO Thread:Thread[http-nio-8080-exec-7,5,main] Instance:server.request.DeviceListRequest@5343acea retCode:-3
[2017-10-18 02:06:39,765] INFO Thread:Thread[http-nio-8080-exec-8,5,main] Instance:server.request.DeviceListRequest@2f15bbce retCode:0
[2017-10-18 02:06:39,765] INFO Thread:Thread[http-nio-8080-exec-8,5,main] Instance:server.request.DeviceListRequest@2f15bbce setResponseObjectWithKey->serverResponse:{"devices":[]} serverResponse_id:636342462
[2017-10-18 02:06:39,765] INFO Thread:Thread[http-nio-8080-exec-8,5,main] Instance:server.request.DeviceListRequest@5343acea serverResponse:{"ret_msg":"unknown","ret_code":-3} serverResponse_id:1626294887
[2017-10-18 02:06:39,766] INFO Thread:Thread[http-nio-8080-exec-7,5,main] Instance:server.request.DeviceListRequest@5343acea retCode:0
[2017-10-18 02:06:39,766] INFO Thread:Thread[http-nio-8080-exec-7,5,main] Instance:server.request.DeviceListRequest@5343acea setResponseObjectWithKey->serverResponse:{"devices":[],"ret_msg":"unknown","ret_code":-3} serverResponse_id:1626294887
[2017-10-18 02:06:39,766] INFO Thread:Thread[http-nio-8080-exec-7,5,main] Instance:server.request.DeviceListRequest@5343acea serverResponse:{"devices":[],"ret_msg":"OK","ret_code":0} serverResponse_id:1626294887
再次,只看线程:和实例:
看看我展示的这两行日志
[2017-10-18 02:06:39,765] INFO Thread:Thread[http-nio-8080-exec-8,5,main] Instance:server.request.DeviceListRequest@2f15bbce setResponseObjectWithKey->serverResponse:{"devices":[]} serverResponse_id:636342462
[2017-10-18 02:06:39,765] INFO Thread:Thread[http-nio-8080-exec-8,5,main] Instance:server.request.DeviceListRequest@5343acea serverResponse:{"ret_msg":"unknown","ret_code":-3} serverResponse_id:1626294887
线程 Thread:Thread[http-nio-8080-exec-8,5,main] 访问对象 DeviceListRequest@2f15bbce 和 DeviceListRequest@5343acea强>
注意:顺便说一下,我使用System.identityHashCode(yourObject) 来获取对象的ID。我正在使用Thread.currentThread() 来获取线程标识符。
我的问题如下: 1.是Thread[http-nio-8080-exec-8,5,main]和Thread[http-nio-8080-exec-7,5,main]两个不同的线程? 2. 名称中包含 main 的线程是否被视为主线程?如果是,那为什么有不止一个主线程? 3. 如何避免有线程访问不是在其上创建的对象的问题?
谢谢!
【问题讨论】:
标签: java multithreading servlets