访问同一个web站点.如果只有你和我两个人访问.那么这站点的服务器会有几个相关的

author author     2023-05-12     513

关键词:

访问同一个web站点.如果只有你和我两个人访问.那么这站点的服务器会有几个相关的线程呢?进程呢?

这和几个用户没关系,和有几个请求有点关系,具体看下面这篇文档:
servlet多线程

Servlet体系结构是建立在Java多线程机制之上的,它的生命周期是由Web容器负责的。当客户端第一次请求某个Servlet时,Servlet容器将会根据web.xml配置文件实例化这个Servlet类。当有新的客户端请求该Servlet时,一般不会再实例化该Servlet类,也就是有多个线程在使用这个实例。 这样,当两个或多个线程同时访问同一个Servlet时,可能会发生多个线程同时访问同一资源的情况,数据可能会变得不一致。所以在用Servlet构建的Web应用时如果不注意线程安全的问题,会使所写的Servlet程序有难以发现的错误。

实例变量不正确的使用是造成Servlet线程不安全的主要原因。下面针对该问题给出了三种解决方案并对方案的选取给出了一些参考性的建议。

  1、实现 SingleThreadModel 接口

  该接口指定了系统如何处理对同一个Servlet的调用。如果一个Servlet被这个接口指定,那么在这个Servlet中的service方法将不会有两个线程被同时执行,当然也就不存在线程安全的问题。这种方法只要将前面的Concurrent Test类的类头定义更改为:

Public class Concurrent Test extends HttpServlet implements SingleThreadModel
…………

  2、同步对共享数据的操作

  使用synchronized 关键字能保证一次只有一个线程可以访问被保护的区段,在本论文中的Servlet可以通过同步块操作来保证线程的安全。同步后的代码如下:

…………
Public class Concurrent Test extends HttpServlet …………
Username = request.getParameter ("username");
Synchronized (this)
Output = response.getWriter ();
Try
Thread. Sleep (5000);
Catch (Interrupted Exception e)
output.println("用户名:"+Username+"
");



  3、避免使用实例变量

  本实例中的线程安全问题是由实例变量造成的,只要在Servlet里面的任何方法里面都不使用实例变量,那么该Servlet就是线程安全的。

  修正上面的Servlet代码,将实例变量改为局部变量实现同样的功能,代码如下:

……
Public class Concurrent Test extends HttpServlet public void service (HttpServletRequest request, HttpServletResponse
Response) throws ServletException, IOException
Print Writer output;
String username;
Response.setContentType ("text/html; charset=gb2312");
……


  对上面的三种方法进行测试,可以表明用它们都能设计出线程安全的Servlet程序。但是,如果一个Servlet实现了SingleThreadModel接口,Servlet引擎将为每个新的请求创建一个单独的Servlet实例,这将引起大量的系统开销。SingleThreadModel在Servlet2.4中已不再提倡使用;同样如果在程序中使用同步来保护要使用的共享的数据,也会使系统的性能大大下降。这是因为被同步的代码块在同一时刻只能有一个线程执行它,使得其同时处理客户请求的吞吐量降低,而且很多客户处于阻塞状态。另外为保证主存内容和线程的工作内存中的数据的一致性,要频繁地刷新缓存,这也会大大地影响系统的性能。所以在实际的开发中也应避免或最小化 Servlet 中的同步代码;在Serlet中避免使用实例变量是保证Servlet线程安全的最佳选择。从Java 内存模型也可以知道,方法中的临时变量是在栈上分配空间,而且每个线程都有自己私有的栈空间,所以它们不会影响线程的安全。

补充:

servlet存在的多线程问题
实例变量: 实例变量是在堆中分配的,并被属于该实例的所有线程共享,所以不是线程安全的.
JSP系统提供的8个类变量:
JSP中用到的OUT,REQUEST,RESPONSE,SESSION,CONFIG,PAGE,PAGECONXT是线程安全的,APPLICATION在整个系统内被使用,所以不是线程安全的.
局部变量: 局部变量在堆栈中分配,因为每个线程都有它自己的堆栈空间,所以是线程安全的.
静态类: 静态类不用被实例化,就可直接使用,也不是线程安全的.
外部资源: 在程序中可能会有多个线程或进程同时操作同一个资源(如:多个线程或进程同时对一个文件进行写操作).

此时也要注意同步问题. 使它以单线程方式执行,这时,仍然只有一个实例,所有客户端的请求以串行方式执行。这样会降低系统的性能
对于存在线程不安全的类,如何避免出现线程安全问题:
1、采用synchronized同步。缺点就是存在堵塞问题。
2、使用ThreadLocal(实际上就是一个HashMap),这样不同的线程维护自己的对象,线程之间相互不干扰。

ThreadLocal的设计
首先看看ThreadLocal的接口:
Object get() ; // 返回当前线程的线程局部变量副本 protected Object
initialValue(); // 返回该线程局部变量的当前线程的初始值
void set(Object value); // 设置当前线程的线程局部变量副本的值
  ThreadLocal有3个方法,其中值得注意的是initialValue(),该方法是一个protected
的方法,显然是为了子类重写而特意实现的。该方法返回当前线程在该线程局部变量的初始
值,这个方法是一个延迟调用方法,在一个线程第1次调用get()或者set(Object)时才执行
,并且仅执行1次。ThreadLocal中的确实实现直接返回一个null:
protected Object initialValue() return null;
  ThreadLocal是如何做到为每一个线程维护变量的副本的呢?其实实现的思路很简单,
在ThreadLocal类中有一个Map,用于存储每一个线程的变量的副本。比如下面的示例实现:

public class ThreadLocal

 private Map values = Collections.synchronizedMap(new HashMap());
 public Object get()
 
  Thread curThread = Thread.currentThread();
  Object o = values.get(curThread);
  if (o == null && !values.containsKey(curThread))
  
   o = initialValue();
   values.put(curThread, o);
  
  return o;
 

 public void set(Object newValue)
 
  values.put(Thread.currentThread(), newValue);
 

 public Object initialValue()
 
  return null;
 


  当然,这并不是一个工业强度的实现,但JDK中的ThreadLocal的实现总体思路也类似于此。
ThreadLocal的使用
  如果希望线程局部变量初始化其它值,那么需要自己实现ThreadLocal的子类并重写该
方法,通常使用一个内部匿名类对ThreadLocal进行子类化,比如下面的例子,SerialNum类
为每一个类分配一个序号:
public class SerialNum

 // The next serial number to be assigned
 private static int nextSerialNum = 0;
 private static ThreadLocal serialNum = new ThreadLocal()
 
  protected synchronized Object initialValue()
  
   return new Integer(nextSerialNum++);
  
 ;

 public static int get()
 
  return ((Integer) (serialNum.get())).intValue();
 


  SerialNum类的使用将非常地简单,因为get()方法是static的,所以在需要获取当前线
程的序号时,简单地调用:

int serial = SerialNum.get(); 即可。
  在线程是活动的并且ThreadLocal对象是可访问的时,该线程就持有一个到该线程局部
变量副本的隐含引用,当该线程运行结束后,该线程拥有的所以线程局部变量的副本都将失
效,并等待垃圾收集器收集。
ThreadLocal与其它同步机制的比较
  ThreadLocal和其它同步机制相比有什么优势呢?ThreadLocal和其它所有的同步机制都
是为了解决多线程中的对同一变量的访问冲突,在普通的同步机制中,是通过对象加锁来实
现多个线程对同一变量的安全访问的。这时该变量是多个线程共享的,使用这种同步机制需
要很细致地分析在什么时候对变量进行读写,什么时候需要锁定某个对象,什么时候释放该
对象的锁等等很多。所有这些都是因为多个线程共享了资源造成的。ThreadLocal就从另一
个角度来解决多线程的并发访问,ThreadLocal会为每一个线程维护一个和该线程绑定的变
量的副本,从而隔离了多个线程的数据,每一个线程都拥有自己的变量副本,从而也就没有
必要对该变量进行同步了。ThreadLocal提供了线程安全的共享对象,在编写多线程代码时
,可以把不安全的整个变量封装进ThreadLocal,或者把该对象的特定于线程的状态封装进
ThreadLocal。
  由于ThreadLocal中可以持有任何类型的对象,所以使用ThreadLocal get当前线程的值
是需要进行强制类型转换。但随着新的Java版本(1.5)将模版的引入,新的支持模版参数
的ThreadLocal<T>类将从中受益。也可以减少强制类型转换,并将一些错误检查提前到了编
译期,将一定程度地简化ThreadLocal的使用。
总结
当然ThreadLocal并不能替代同步机制,两者面向的问题领域不同。同步机制是为了同
步多个线程对相同资源的并发访问,是为了多个线程之间进行通信的有效方式;而
ThreadLocal是隔离多个线程的数据共享,从根本上就不在多个线程之间共享资源(变量)
,这样当然不需要对多个线程进行同步了。所以,如果你需要进行多个线程之间进行通信,
则使用同步机制;如果需要隔离多个线程之间的共享冲突,可以使用ThreadLocal,这将极
大地简化你的程序,使程序更加易读、简洁。

ThreadLocal常见用途:
存放当前session用户
存放一些context变量,比如webwork的ActionContext
存放session,比如Spring hibernate orm的session

例子:用 ThreadLocal 实现每线程 Singleton
线程局部变量常被用来描绘有状态“单子”(Singleton) 或线程安全的共享对象,或者是通过把不安全的整个变量封装进 ThreadLocal,或者是通过把对象的特定于线程的状态封装进 ThreadLocal。例如,在与数据库有紧密联系的应用程序中,程序的很多方法可能都需要访问数据库。在系统的每个方法中都包含一个 Connection 作为参数是不方便的 — 用“单子”来访问连接可能是一个虽然更粗糙,但却方便得多的技术。然而,多个线程不能安全地共享一个 JDBC Connection。如清单 3 所示,通过使用“单子”中的 ThreadLocal,我们就能让我们的程序中的任何类容易地获取每线程 Connection 的一个引用。这样,我们可以认为 ThreadLocal 允许我们创建每线程单子。
例:把一个 JDBC 连接存储到一个每线程 Singleton 中
public class ConnectionDispenser
private static class ThreadLocalConnection extends ThreadLocal
public Object initialValue()
return DriverManager.getConnection(ConfigurationSingleton.getDbUrl());


private ThreadLocalConnection conn = new ThreadLocalConnection();
public static Connection getConnection()
return (Connection) conn.get();



注意:
理论上来说,ThreadLocal是的确是相对于每个线程,每个线程会有自己的ThreadLocal。但是上面已经讲到,一般的应用服务器都会维护一套线程池。因此,不同用户访问,可能会接受到同样的线程。因此,在做基于TheadLocal时,需要谨慎,避免出现ThreadLocal变量的缓存,导致其他线程访问到本线程变量。

参考资料:http://blog.csdn.net/explorering/article/details/1330744

参考技术A 肯定都是一个,这个和几个用户访问没有关系,如果多一个用户就会增加一个线程或进程,那访问量大一点服务器可能就挂了本回答被提问者采纳 参考技术B
另外,虚机团上产品团购,超级便宜

ubuntu搭建web站点并发布公网访问内网穿透(代码片段)

文章目录前言1.本地环境服务搭建2.局域网测试访问3.内网穿透3.1ubuntu本地安装cpolar3.2创建隧道3.3测试公网访问4.配置固定二级子域名4.1保留一个二级子域名4.2配置二级子域名4.3测试访问公网固定二级子域名前言网:我们通常... 查看详情

如何在一个服务器上,同时开两个网站。(只有一个ip地址)

要求:一个网站固定用ip地址进行访问。如:http://12.0.0.1(这个是默认的,只要用这个IP登录,就必须打开这个网页)另一个网站用绑定域名的方式进行访问.如:http://www.ccc.com请高手给出详细解答过程。非常感谢~!非常感谢回答... 查看详情

本地网站上线ubuntu搭建web站点,并内网穿透发布公网访问(代码片段)

...地网站上线】ubuntu搭建web站点,并内网穿透发布公网访问前言1.本地环境服务搭建2.局域网测试访问3.内网穿透3.1ubuntu本地安装cpolar3.2创建隧道3.3测试公网访问4.配置固定二级子域名4.1保留一个二级子域名4.2配置二级子域名4.3... 查看详情

android上怎么访问本地html网页

如果你是打算用手机测试移动版网页的话(同局域网手机访问pc上的html)。那可以将局域网内的设备都设置成静态ip。然后使用iis或php环境将网页放到站点目录下。然后就可以通过ip进行访问了。如果你打算用手机访问手机上的ht... 查看详情

通过受限访问 URL 从另一个站点访问一个站点的问题

】通过受限访问URL从另一个站点访问一个站点的问题【英文标题】:IssueinaccessingonesitefromanothersitethroughlimitedaccessURL【发布时间】:2020-05-0514:29:37【问题描述】:我有两个网站,都在不同的域中。所以例如http://example1.com和http://exa... 查看详情

httpd虚拟主机(代码片段)

...之后,能够服务于多个不同的站点,这就意味着我们通过同一个主机访问多个不同的站点,它们打开展示的资源是不同的,而且对于终端用户来讲,它们意识不到这是个虚拟主机,甚至于它能够完全认为这是一台运行的独立的物... 查看详情

windows启动一个ftp站点,让局域网的人访问/写

  现在需要一台局域网的电脑启动一个ftp站点,该电脑需要进行以下步骤:https://blog.csdn.net/m0_50298323/article/details/128404598    查看详情

验证站点/应用程序以访问 Web API 服务

】验证站点/应用程序以访问WebAPI服务【英文标题】:Authenticateasite/apptoaccessaWebAPIService【发布时间】:2014-07-0606:07:51【问题描述】:简短的问题:我有一个.NET中的WebAPI服务,以及一个仅使用HTML和AngularJS制作的站点。如何才能只... 查看详情

session和cookie的区别

...一个浏览器是共享一个session,就算有两个web项目部署在同一个服务器上,针对两个项目的session是不同的如:你在tomcat上同时部署了两个web项目,分别是web1、web2。当你在一个浏览器上同时访问web1时创建的session是A1,访问web2时创... 查看详情

访问远程站点上的科尔多瓦

】访问远程站点上的科尔多瓦【英文标题】:getaccesstocordovaonremotesite【发布时间】:2017-06-1411:52:02【问题描述】:我开发了一个渐进式web应用程序,并想使用cordova和一个cordovaFCM插件在iOS上显示通知,我如何在cordova中远程加载我... 查看详情

iis建立的网站怎样才能让人远程访问

局域网可以访问但是远程访问不了登录域名管理面板。选择需要设置的域名,选择功能按钮:解析添加域名前缀BBS或其他域名以及对应的服务器地址。确定解析,等待生效即可。IIS的域名绑定就直接了:首先建立站点:第一步:... 查看详情

nginx浏览器开启密码验证

...站点内容或者流量的关系,我们并不想让所有人都能正常访问,那么我们可以设置访问认证。只有让用户输入正确的用户名和密码才能正常访问。效果如下:在nginx下,提供了ngx_http_auth_basic_module模块实现让用户只有输入正确的... 查看详情

关于用两个网址访问一个服务器上不同站点

要求就是通过http://www.xiaolu.com访问在位置f:myblog下的文件index.html;通过http://www.xiaolu1.com访问在位置f:myblog1下的index.htm文件解决方法一、1、配置httpd.conf文件,启用httpd-vhosts.conf即,将#Includeconf/extra/httpd-vhosts.conf前面的#去掉2、配置h... 查看详情

如果在一个服务器上绑定多个域名?

....haojz.comwww.00991.comwww.vvnet.net如何把这三个域名同时绑定在同一个服务器上,对应不同的网站?Windows2003服务器建立web站点并发布:利用Windows2003中的IIS6组件实现让多个不同的网站都用80端口对外发布,而访问时直接输入地址即可... 查看详情

iis如何通过一个外网ip端口把内网多个站点发布到外网

参考技术A这个可以通过NAT映射来实现在访问外部IP地址时,自动转向内部IIS所在的IP地址,例如:内部IP地址是:X,外部IP地址是:Y,内部映射可以将X的80端口映射到外部IP地址Y上面,这样如果有人访问外部IP或者域名(域名必... 查看详情

cookie是啥,它有啥用

...用户请求和页面在Web服务器和浏览器之间传递。用户每次访问站点时,Web应用程序都可以读取Cookie包含的信息。假设在用户请求访问您的网站www.contoso.com上的某个页面时,您的应用程序发送给该用户的不仅仅是一个页面,还有一... 查看详情

nginx怎么配置多个web

...的web服务站点,nginx是定时检测其可用性的。你说的需要访问多次就能访问到,那只是一个假象。其实是刚好nginx完成了管辖下的站点的检查,将刚重启的tomcat加入到了可用列表中;在你的请求到达时,被转发到了这个tomcat。 查看详情

目录遍历攻击详解

对于一个安全的Web服务器来说,对Web内容进行恰当的访问控制是极为关键的。目录遍历是Http所存在的一个安全漏洞,它使得攻击者能够访问受限制的目录,并在Web服务器的根目录以外执行命令。  Web服务器主要提供两个级别... 查看详情